block定义
再看看值捕获的问题
struct Block_descriptor {
unsigned long int reserved;
unsigned long int size;
void (*copy)(void *dst, void *src);
void (*dispose)(void *);
};
struct Block_layout {
void *isa;
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor *descriptor;
/* Imported variables. */
};
实际上block就是这俩玩意了
我们来举个栗子看看定义一个最简单block 打印hello world
使用clang指令clang -rewrite-objc main.m
得到一个cpp文件
打开之,你就会看到什么是block了你定义完block之后,其实是创建了一个函数,在创建结构体的时候把函数的指针一起传给了block,所以之后可以拿出来调用。
再看看值捕获的问题
定义block的时候,变量a的值就传递到了block结构体中,仅仅是值传递,所以在block中修改a是不会影响到外面的a变量的。
而加了__block前缀并不是直接传递a的值了,而是把a的地址传过去了,所以在block内部便可以修改到外面的变量了。
根据isa指针,block一共有3种类型的block
_NSConcreteGlobalBlock 全局静态
_NSConcreteStackBlock 保存在栈中,出函数作用域就销毁
_NSConcreteMallocBlock 保存在堆中,retainCount == 0销毁
而ARC和MRC中,还略有不同