__block修饰符的内存管理
当block在栈上时,并不会对__block变量产生强引用
当__block修饰指针变量时,会在成的
__Block_byref_xxx_0
结构体中生成
从copy函数和dispose函数:
void (*__Block_byref_id_object_copy)(void*, void*);
void (*__Block_byref_id_object_dispose)(void*);
当block被copy到堆时
- 会调用block内部的copy函数
- copy函数内部会调用_Block_object_assign函数
- _Block_object_assign函数会对__block变量形成强引用(retain)
当block从堆中移除时
- 会调用block内部的dispose函数
- dispose函数内部会调用_Block_object_dispose函数
- _Block_object_dispose函数会自动释放引用的__block变量(release)
示例代码:
__block int lisi_age = 18;
block b = ^{
NSLog(...);
};
b();
生成的__main_block_impl_0
结构体
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
__Block_byref_lisi_age_1 *lisi_age; // by ref
}
生成的__main_block_desc_0
结构体
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);
void (*dispose)(struct __main_block_impl_0*);
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0};
__block修饰的指针类型变量生成的__Block_byref_lisi_age_1
结构体
struct __Block_byref_lisi_age_1 {
void *__isa;
__Block_byref_lisi_age_1 *__forwarding;
int __flags;
int __size;
int lisi_age;
};
__Block_byref_lisi_age_1 lisi_age = {
(void*)0,
(__Block_byref_lisi_age_1 *)&lisi_age,
0,
sizeof(__Block_byref_lisi_age_1),
18
};