Block介绍(二)内存管理与其他特性

Block-栈,堆,全局块 栈块、堆块、全局块 (Block详解)对于Block之前只是在用,对于栈,堆这块没有细入研究,今天抽空把”Effectiv Objective-c 2.0”这本书看了一下,下面是一些概念及实例。分几类 栈Block 堆Block 全局Block 栈Block直接声明使用的block是分配在栈内,为栈block,只会在定义它的范围内有效。 注意:下面这种写法就有问题。 -(void)doSomet 阅读详情

我们在前一章介绍了block的用法,而正确使用block必须要求正确理解block的内存管理问题。

这一章,我们只陈述结果而不追寻原因,我们将在下一章深入其原因。

一、block放在哪里

我们针对不同情况来讨论block的存放位置:

1.栈和堆

以下情况中的block位于堆中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void foo()
{
     __block int i = 1024 ;
     int j = 1 ;
     void (^blk)( void );
     void (^blkInHeap)( void );
     blk = ^{ printf( "%d, %d\n" , i, j);}; //blk在栈里
     blkInHeap = Block_copy(blk); //blkInHeap在堆里
}
 
- ( void )fooBar
{
     _oi = 1 ;
     OBJ1* oj = self ;
     void (^oblk)( void ) = ^{ printf( "%d\n" , oj.oi);};
     void (^oblkInHeap)( void ) = [oblk copy ]; //oblkInHeap在堆中
}

 

2.全局区

以下情况中的block位于全局区: 

1
2
3
4
5
6
7
8
9
10
static int (^maxIntBlock)( int , int ) = ^( int a, int b){ return a>b?a:b;};
- ( void )fooBar
{
      int (^maxIntBlockCopied)( int , int ) =[maxIntBlock copy ];
}
 
void foo()
{
      int (^maxIntBlockCopied)( int , int ) = Block_copy(maxIntBlock);
}

需要注意的是,这里复制过后的block依旧位于全局区,实际上,复制操作是直接返回了原block对象。 

 

二、block引用的变量在哪里

 1.全局区

全局区的变量存储位置与block无关:

1
2
3
4
5
6
7
8
static int gVar = 0 ;
//__block static int gMVar = 1;
 
void foo()
{
     static int stackVar = 0 ;
//    __block static int stackMVar = 0;
}

注意,static变量是不允许添加__block标记的

 

2.堆栈 

此时,你可能会问,当函数foo返回后,栈上的j已经回收,那么blkInHeap怎么能继续使用它?这是因为没有__block标记的变量,会被当做实参传入block的底层实现函数中,当block中的代码被执行时,j已经不是原来的j了,所谓物是人非就是这样吧~

另外,如果使用到变量j的所有block都没有被复制至heap,那么这个变量j也不会被复制至heap。

因此,即使将j++这一句放到blk()这句之前,这段代码执行后,控制台打印结果也是:1024, 1。而不是1024, 2

 

 

三、其他特性

1.复制的行为

 对block调用复制,有以下几种情况:

1.对全局区的block调用copy,会返回原指针,并且这期间不处理任何东西(至少目前的内部实现是这样);

2.对栈上的block调用copy,每次会返回新复制到堆上的block的指针,同时,所有__block变量都会被复制至堆一份(多次拷贝,只会生成一份)。

3.对已经位于heap上的block,再次调用copy,只会增加block的引用计数。

为什么我们不讨论retian的行为?原因是并没有Block_retain()这样的函数,而且objc里面的retain消息发送给block对象后,其内部实现是什么都不做。 

2.objc类中的block复制

 objc类实例方法中的block如果被复制至heap,那么当前实例会被增加引用计数,当这个block被释放时,此实例会被减少引用计数。

但如果这个block没有使用当前实例的任何成员,那么当前实例不会被增加引用计数。这也是很自然的道理,我既然没有用到这个instance的任何东西,那么我干嘛要retian它?

我们要注意的一点是,我看到网上有很多人说block引起了实例与block之间的循环引用(retain-cycle),并且给出解决方案:不直接使用self而先将self赋值给一个临时变量,然后再使用这个临时变量。

但是,大家注意,我们一定要为这个临时变量增加__block标记(多谢第三篇文章回帖网友的提醒)。

 

这一章我们以结果导向的方式来说明了各种情况下,block的内存问题,下一章,我将剖析运行时库的源码,从根源阐述block的行为。也就是过程导向的方式了。

ios-block的局部变量和全局变量和static的静态变量联系.zip block,局部变量,全部变量,static的静态变量关系 立即下载

相关推荐

从IMU到机器人定位:手把手教你用ESKF(Error-State Kalman Filter)搞定传感器融合

本文详细介绍了如何使用ESKF(Error-State Kalman Filter)实现IMU与多传感器的融合,解决机器人定位中的积分漂移问题。通过代码示例和Gazebo仿真案例,展示了ESKF在自动驾驶和移动机器人中的核心应用,包括误差状态建模、预测过程实现和观测更新策略,帮助开发者掌握这一高效滤波技术。

weixin_33275503的博客 278

iOS学习之Block内存管理详解

在ios开发中,相信说道block大家都不陌生,内存管理问题也是开发者最头疼的问题,网上很多讲block的博客,但大都是理论性多点,今天结合一些实例来讲解下。   存储域   首先和大家聊聊block的存储域,根据block在内存中的位置,block被分为三种类型:   NSGlobalBlock   NSStackBlock   NSMallocBlock  

qq_32506555的博客 432

关于solidworks无法获得下列许可SOLIDWORKS Standard的解决方法

在使用solid works的时候,出现无法获得下列许可SOLIDWORKS Standard,刚开始还以为软件出了问题,经过一方折腾找到了解决方法。希望这个方法可以帮助到您 找到这个服务 问题到这里就已经得到了解决,但更大的问题是,要是每次遇见这种都要这么麻烦,岂不是很累?这里也提供一种方法。考虑到每个人的情况,下面说的可能有一点啰嗦。 !!!!!!注意那个在此期间之后重新启动服...

Chaosna13的博客 7万+

IOS内存管理

1. 栈区(stack):由编译器自动分配释放,函数的参数值,局部变量等值。2. 堆区(heap):一般由开发人员分配释放,若不释放,则可能会引起内存泄漏。Objective-C提供了两种种内存管理方式:(MRC,手动引用计数器),(ARC,自动引用计数)。ARC作为苹果新提供的技术,苹果推荐开发者使用ARC技术来管理内存;

风·之痕的博客 8482

【Photoshop JSX脚本】强大的事件监听器脚本 - event_listener.jsx

新手第一次了解的事件监听一定是ScriptingListener.8bi插件,如果你对此插件有了基本运用,那么现在了解一款更方便的时间监听脚本event_listener.jsx。不再像ScriptingListener.8bi插件那样晦涩难懂。 1、准备event_listener.jsx文件到 F:\Program Files\Adobe Photoshop 2020\Presets\...

Greless的后花园 8205

[QMT量化交易小白入门]-九十五、多因子选股和趋势择时股票量化交易策略,年化收益率40.61%

本策略采用“双层过滤”机制:第一层基于多维度财务指标进行股票池筛选(多因子选股),第二层运用均线系统和MACD指标实施动态择时(趋势跟踪)。这种设计既保证了组合的质量下限,又能灵活应对市场波动。因子配置科学性:涵盖估值、成长、盈利、动量四大类因子风险控制精细化:设置动态止损与仓位管理机制信号验证严格性:多重条件交叉验证提升胜率。

木头大左的博客 798

3.代码块(BLOCK)—static 修饰分类说明和使用(了解)

//代码块形式: { 代码块 } 1.作用; 用来初始化类或对象 2.代码块如果有修饰只能用static修饰 : 所以就有非静态代码块和 静态代码块两种 { 代码块 }

Aeiou.a1的博客 202

大厂面经:京东大数据面试题及参考答案(3万字长文)

Kafka是一个开源的分布式流处理平台,由 LinkedIn 开发并在 2011 年贡献给 Apache 软件基金会。高吞吐量:能够处理大量的数据流,适合实时数据管道。持久性:数据存储在磁盘上,确保数据不丢失。容错性:通过数据复制提供高可用性。扩展性:支持水平扩展,易于增加更多节点。Kafka 的核心概念Topic:逻辑上的数据流,可以理解为主题。Producer:生产数据的应用程序。Consumer:消费数据的应用程序。Broker:Kafka 集群中的服务器节点。Partition。

大模型大数据攻城狮的专栏 863

浅谈iOS中Block的内存管理

一、前言:  Block是Objective-C中的一项强大的特性,Block可以看作是OC中对于闭包函数的实现,实质上Block也是一个对象~   二、内存分配区域: OC中的各个主要的内存分配区域:包括有--栈区、堆区、常量区、全局静态区、文本区(代码区)   内存分配区域 栈区:存放函数参数值、局部变量、函数返回地址等,我们每次调用函数,都会执行压栈操作(在XCode的左侧...

wqt925497045的博客 437

华为OD面试八股真题 - 操作系统相关 - 2

华为OD技术面,操作系统相关八股真题提供详细解答,这篇博客主要涉及于进程和线程相关知识点

qq_45776114的博客 965

基于A*算法的二维栅格地图路径规划与避障MATLAB仿真

本文将介绍如何使用MATLAB编写基于A*算法的二维栅格地图路径规划与避障的仿真程序。我们可以使用二维数组表示地图,其中每个元素表示一个栅格的状态,例如1表示障碍物,0表示可行走区域。接下来,我们需要定义A*算法的节点类。G值表示从起始节点到当前节点的代价,H值是启发式函数估计的从当前节点到目标节点的代价。算法,我们可以有效地找到起始点到目标点的最短路径,并在仿真中进行可视化展示。算法的基本思路是从起始节点开始,按照一定的启发式函数选择下一个节点,直到找到目标节点或者遍历完所有可行走区域。

ByteWhizX的博客 1273

iOS中Block介绍(二)内存管理与其他特性

iOS中Block介绍(二)内存管理与其他特性 一、block放在哪里 我们针对不同情况来讨论block的存放位置: 1.栈和堆 以下情况中的block位于堆中: voidfoo() { __blockinti=1024; intj=1; void(^blk)(void); void(^blk...

68

用一个稳定的 Deep Link,直接打开 SAP CRM WebClient 里的 Sales Order 创建界面

本文详细介绍了如何在SAP CRM WebClient UI中构建直接进入销售订单创建页面的Deep Link URL。关键步骤包括:1) 通过SMICM和SICF确认系统入口路径及端口;2) 使用BSP_DLC_SDESIGN或F2功能获取Sales Order的对象类型;3) 确保创建动作(D)能正确映射到目标页面;4) 按规范拼接包含sap-client、saprole等参数的完整URL。文章还提供了ABAP代码示例自动生成URL,并提醒注意浏览器缓存问题。通过这种标准化导航方式,可以实现稳定的页面直

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 209

基于STM32的超声波雾化片驱动电路设计

在高频驱动与功率变换技术中,压电陶瓷负载的匹配设计是一项典型的嵌入式工程挑战。STM32作为灵活的主控平台,通过产生频率和占空比可调的PWM信号,配合驱动电路和匹配网络,即可实现高效稳定的超声波雾化功能。本文从反激变换器的工作原理出发,分析谐振频率匹配、MOS管驱动、变压器参数计算等核心技术价值,并结合加湿器、医用雾化器等实际场景,说明如何利用MCU实现自动追频、缺水保护和功率调节。不同于纯模拟方案,基于STM32的软件控制让系统具备可调性与扩展性,为产品化落地提供了可靠路径。文章详细介绍了硬件选型、PCB

weixin_33911824的博客 370

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

上一篇: Block介绍(一)基础
下一篇: block介绍(三)揭开神秘面纱(上)
focusjava
博客等级 码龄14年 127粉丝 528原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值