持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第6天,点击查看活动详情
前言
在iOS面试中,block这个问题出现的频率虽然不是最高的,但是会和很多实际开发过程中的问题结合起来问,所以弄懂其中原理还是比较重要的,下面咱们就来看看,block的一些关键原理把。
第一重:解释block
- block是将函数及其执行上下文封装起来的对象
第二重:block截获变量
- 局部变量
-
- 基本数据类型(只截获其值)
-
- 对象类型(连同所有权修饰符一起截获)
- 静态局部变量(指针形式截获)
- 全局变量(不截获)
- 静态全局变量(不截获)
第三重:__block修饰符
- 对被截获变量进行赋值操作就需要添加__block
- 赋值 不等于 使用
-
需要__block修饰符的 【局部变量(基本数据类型、对象类型)】
-
不需要__block修饰的
1) 静态局部变量
2)全局变量
3)静态全局变量
第四重:block内存管理
- _NSConcreteGlobalBlock(全局)
- _NSConcreteStackBlock(栈)
- _NSConcreteMallocBlock(堆)
Block的copy操作
第五重:block循环引用
为什么会产生循环引用?
1,如果当前block对当前对象的某一成员变量进行截获的话,就会对这个成员变量进行强引用,同时当前对象也对这个block进行copy修饰,也是一个强引用,所以会产生自循环引用,可以通过声明其为__weak变量,从而进行消除
2,如果说我们声明一个__block修饰符的话,在MRC下不会产生(因为不会产生引用计数),在ARC下我们可以通过断环的方式进行打破循环引用
Ps:为了保证block的释放正和时宜,而不是像在栈空间上的变量似的随时可能被释放。在MRC的时候声明一个block的时候通常使用copy关键字修饰,而到了ARC虽然不用我们显式的执行copy,为了提醒我们block是通过copy操作存在于堆空间的我们还是会用copy关键修饰,这只是一个习惯,其实用strong也是可以的。