Blocks 模式
Block语法
- ^ 返回值类型 参数列表 表达式
- ^ 参数列表 表达式 (省略返回值类型)
- ^ 表达式 (省略参数列表)
Block变量类型
- 自动变量: 返回值类型 (^类型名称)(参数列表)
- 函数参数: 返回值类型 (^类型名称)(参数列表) 返回值参数: ^类型名称()(参数列表) 使用typedef 更方便
- 参考
Blocks的实现
Block的实质
- __main_block_impl_0(__main_block_func_0,__main_block_desc_0_DATA)
- blik = __main_block-impl_0
- blk->FuncPtr
自动获取外部变量
- 通过参数值传递到__main_block_impl_0获取
__block说明符
- __Block_byref_intValue_0结构体:封装__block修饰的外部变量
- _Block_object_assign函数:当block从栈拷贝到堆时,调用
- _Block_object_dispose函数:当block从堆内存释放时,调用此函数
Block 存储域
- _NSConcertStackBlock(栈) _NSConcertGlobalBlock(程序的数据区域.data区) _NSConcertMallocBlock(堆)
- block 作为方法或函数的参数传递时,编译器不会自动调用 copy 方法;
- 当block作为函数返回值返回时,编译器将block作为_Block_copy函数
- 当 block 被赋值给 __strong id 类型的对象或 block 的成员变量时,编译器自动将 block 作为 _Block_copy
- 当 block 作为参数被传入方法名带有 usingBlock 的 Cocoa Framework 方法或 GCD 的 API 时。这些方法会在内部对传递进来的 block 调用 copy 或 _Block_copy 进行拷贝;
__block变量的内存管理
- 当Block从栈复制到堆时,使用的所有__block变量也从栈复制到堆,此时block持有__block变量
- __forwarding:不管__block变量在栈上还是堆上,都能正确的访问该变量
截获对象
- 当 block 调用 copy 方法时,如果 block 在栈上,会被拷贝到堆上;
- 当 block 作为函数返回值返回时,编译器自动将 block 作为 _Block_copy 函数,效果等同于 block 直接调用 copy 方法;
- 当 block 被赋值给 __strong id 类型的对象或 block 的成员变量时,编译器自动将 block 作为 _Block_copy 函数,效果等同于 block 直接调用 copy 方法;
- 当 block 作为参数被传入方法名带有 usingBlock 的 Cocoa Framework 方法或 GCD 的 API 时。这些方法会在内部对传递进来的 block 调用 copy 或 _Block_copy 进行拷贝;