Block
block的原理是什么 本质是什么
本质是一个 oc 对象, 内部也有一个 isa 指针
内部封装了 block 执行逻辑的函数
Block 的本质
结构体对象
int age = 20;
void (^block) (void) = ^ {
NSLog(@"age is %d", age);
};
变量自动捕获👇
struct __main_block_impl_0 {
struct __block_impl impl; //impl 结构体见👇
struct __main_block_desc_0* Desc;
int age;// 自动变量捕获
}
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr; //指向 block 内部实现的函数地址 (见👇)
}
// 封装了 block 执行逻辑的函数
static void __main_block_func_0 () {
//TODO
}
变量捕获
| 标题 | 是否捕获 | 捕获方式 |
|---|---|---|
| auto变量 | 捕获 | 值传递 |
| static | 捕获 | -- |
| 全局变量 | 不捕获 | 直接访问 |
局部变量需要捕获是因为需要跨函数访问
Block 类型
继承自NSBlock类型
globleBlock 没有访问 auto 变量 (访问 static 和 全局变量仍让是 globelBlock)
stackBlock 访问了 auto 变量 (MRC 下能打印出来, ARC下会自动调动 copy ---> mallocBlock)
mallocBlock ----> stackBlock 调用了 copy (栈 --- > 堆上)
__block的作用
__block 可解决 block 内部无法修改 auto 变量的问题
编译器会将__block变量包装成一个对象 __Block_byref_xxx_0
基本数据类型 int age = 0; 编译器会将 age 包装成 __Block_byref_age_0 结构体
1.__main_block_impl_0 结构体内持有 __Block_byref_age_0
2.__Block_byref_age_0 内部持有 __forwarding 指针指向自己
Block 内存管理
当 block 被 copy 到堆上时,会调用block内部的 copy 函数,copy 函数会调用 __Block_object_assign