iOS中的Block
Block的种类
-
NSConcreteGlobalBlock
Block内部没有引用外部变量时,block的类型就是GlobalBlock,而且GlobalBlock是全局block,保存在程序数据区(.data区域)如下图所示
594FD12E-4FFA-4CCB-8DD9-2E5C856B7673.png
-
NSConcreteStackBlock
顾名思义它是保存到栈上,当Block引用了外部局部变量时,block的类型就是StackBlock,如下图所示
5D35F538-9048-470C-8413-BEAACB919CEE.png
但GlobalBlock和StackBlock区别在哪里呢?实际上stackBlock会在block内部用一个结构体__main_block_impl_0
保存外部变量,但没有对外部对象持有引用,所以变量引用计数不变。
注意一点
关于block引用外界变量的问题,其实也分很多情况,比如引用的外界变量是static修饰的变量或者全局变量的话,它依然是GlobalBlock。
-
NSConcreteMallocBlock
当block进行了copy操作时,block的类型就变成MallocBlock,这时它保存到堆上,注意MallocBlock会持有外部变量
6A4F3690-50C8-400C-81C6-469E5D985E53.png
-
关于block
我们知道,变量用__block
修饰可以在block内部更改变量的值,原因在于存在栈上的变量拷贝到堆上。
注意!!这里需要知道的是,在MRC环境下,如果没有用__block
,会对外部对象采用copy的操作,而用了__block
则不会用copy的操作。
而在ARC环境下,对于声明为__block的外部对象,在block内部会进行retain,以至于在block环境内能安全的引用外部对象,所以要谨防循环引用的问题 -
关于循环引用
一句话可以概括:判断持有block的对象是否也被block持有,如果有则出现循环引用。
Ref
让我们来深入浅出block吧 - 简书
block使用小结、在arc中使用block、如何防止循环引用 - CSDN博客
Block基础和retain cycle(循环引用) - 简书
谈Objective-C block的实现 | 唐巧的博客
__block存储类型 - Nonato - 博客园
Block 原理详解 - CSDN博客
Block基础和retain cycle(循环引用) - 简书
block没那么难(三):block和对象的内存管理 - 作业部落 Cmd Markdown 编辑阅读器
正确使用Block避免Cycle Retain和Crash - Cooper’s Blog
【小测试】你真的知道blocks在Objective-C中是怎么工作的吗?(获奖公布) | 灌水大厅 - CocoaChina CocoaChina_让移动开发更简单
clang -rewrite-objc的使用点滴