一、Block本质
1.1、概念
Block是将函数及其执行上下文封装起来的对象。
问题1:什么是Block?
Block是将函数及其执行上下文封装起来的对象。
问题2:什么是Block调用?
Block调用就是函数调用。
1.2、代码转换指令
编译命令二、Block截获变量
问题2:截获变量面试题
截获变量答案是12。
2.1、截获变量类型分类
截获类型 截获特性问题3:关于Block的截获变量特性怎么理解?
从截获类型和截获特性进行解释(见上图)。
三、__block修饰符
3.1、赋值和使用的区别
使用
不需要使用__block
赋值
需要使用__block
3.2、使用场景细分
问题4:什么场景使用__block修饰符?
__block使用场景 使用__block 不使用__block问题5:__block笔试题
__block修饰基本数据类型解释原因:
1、__block修饰的变量变成了对象,如下:
对象模型
2、后面使用的multiplier都是结构体里面的,通过forwarding指针引用,如下:
3、又因为在Block在栈上,__block的forwarding指针指向自己,如下图:
4、所以这里修改的multiplier也就是修改栈上的变量。而Block在栈上,所以使用的也是栈上的变量。
补充:__block在ARC和MRC区别
- MRC 环境下,block 截获外部用 __block 修饰的变量,不会增加对象的引用计数
- ARC 环境下,block 截获外部用 __block 修饰的变量,会增加对象的引用计数
四、Block内存管理
4.1、Block类型
Block类型4.2、Block内存区域
Block内存区域4.3、Block的Copy操作
Block的Copy操作注意:
对Block的Copy操作理解,会将Block从栈放到堆上,防止使用的时候,Block被销毁。
所以,一般声明的Block成员变量关键字是Copy。
4.4、栈上Block的销毁
栈上Block的销毁4.5、栈上Block的Copy
问题6:当把栈上的Block进行Copy操作之后,在MRC环境下,是否会引起内存泄漏?
是的
4.6、栈上__block变量的Copy
栈上__block变量的Copy所以一旦被Copy到堆上,即使代码表面上是修改栈上的__block变量,其内在本质是修改堆上的__block变量。
例题实战
例题实战- _blk进行了Copy操作,里面的multiplier用的是堆上的。
- multiplier = 6其实是通过栈上的forwarding修改堆上的multiplier。
- 结果是 4 * 6 = 24。
4.7、forwarding指针总结
总结- 如果没有对__block进行Copy操作,就是操作栈上的__block变量。
- 如果发生了Copy操作,无论是在栈上还是在堆上,都是操作堆上的__block变量。
五、Block循环引用问题
问题7:以下代码有什么问题?
题目有循环引用。
原因:
- 根据Block截获变量的特性,对于对象,会将所有权修饰符一起截获。
- 这里对象持有Block,又因为array是strong,所以Block对array也是strong。
解决办法:
- 也是从截获变量特性解释
问题8:以下代码有问题吗?
循环引用答案:
答案
解释:
在ARC情况下
解决办法:
问题9:为什么Block会产生循环引用?
从截获变量特性进行答题
问题10:怎样理解Block截获变量对特性?
理解问题11:你遇到过哪些循环引用?你又是怎样解决的?
- NSTimer
- Block
网友评论