在OC中,C语言结构体不能含有__strong修饰符的变量,因为编译器不知道什么时候初始化和废弃C语言结构体,不能很好的管理内存。
OC的运行时库能够准确地把握block从栈复制到堆以及堆上的block被废弃的时机,所以block结构体中即使含有__strong或者__weak修饰符的变量,也可以恰当地进行初始化和废弃。
- 在__main_block_desc_0结构体中增加的成员变量进行copy和dispose
- 通过指针赋值给该成员变量的__main_block_copy_0函数和__main_block_dispose_0函数
__main_block_copy_0函数
:使用_block_object_assign函数将对象类型的对象赋值给block结构体中的成员变量,相当于retain实例方法
__main_block_dispose_0函数
:使用_block_object_dispose函数释放赋值在block结构体中的成员变量,相当于release实例方法
__main_block_copy_0与__main_block_dispose_0的调用时机如下:
函数 | 调用时机 |
---|---|
__main_block_copy_0 | 栈上的block复制到堆上时 |
__main_block_dispose_0 | 堆上的block被废弃时 |
栈上的block复制到堆上,主要有以下几种情况
- 调用block的copy实例方法
- block作为函数返回值返回时
- 将block赋值给__strong修饰的id类型的类或block类型成员变量时
在Cocoa框架中含有usingBlock的方法或者GCD中API传递block时
block在截获对象时和使用__block变量时的不同
截获的是对象 | BLOCK_FIELD_IS_OBJECT |
---|---|
截获的是__block变量 | BLOCK_FIELD_IS_BYREF |
可以通过这2个不同的参数来区分__main_block_copy_0函数和__main_block_dispose_0函数的对象类型是对象还是__block变量。
block中使用的赋值给__strong修饰符的自动变量的对象和复制到堆上的__block变量由于被堆上的block所持有,所以可以超出其变量作用域而存在
又见block(一):block是什么?
又见block(二):block语法定义
又见block(三):block实质
又见block(四):block捕获自动变量
又见block(五): __block变量和对象
又见block(六):block存储域与__block变量存储域