Blocks篇:2.Blocks的调用过程及其对象本质
|
|
- 使用”clang -rewrite-objc main.m“转换后的代码为:
|
|
- 以上代码中,在main函数中,简化后的myBlock声明为:
|
|
- 简化后的myBlock调用为:
|
|
由此,在编译期间,我们了解了Blocks的声明和整个调用过程:
- 系统在原声明Block的生命周期外,生成静态的相关Block结构体、描述信息结构体和执行函数等。
- 在原声明Block的生命周期内部,使用相关结构体创建并生成Block的实例。
- 根据生成的Block实例,找到其中的C函数指针,进行调用。
2.Blocks是对象
对于Block变量的本质,上面代码中可以看出:
- 在Block的结构体__block_impl中,包含了isa成员变量,是(void *)类型;
- isa变量在初始化Block时,赋值的是_NSConcreteStackBlock的地址;
2.1 isa
我们知道,isa标识的是OC对象的类型。在objc-private.h中可以找到声明:
|
|
在以上代码中可以看到:
- id(我们说的OC对象),即objc_object结构体指针,其类型的实质,就是isa联合体的cls成员,也就是指向的Class;
- 由于objc_class“继承”了objc_object结构体,故其中也包含了isa成员,即“类”也标识了自己所属的类(metaclass,说多了…)。
2.2 _NSConcreteStackBlock类型
- 对于_NSConcreteStackBlock,我们可以在main.cpp中找到其声明:
|
|
可以看到,_NSConcreteStackBlock声明的是一个数组的指针。
- 而在GNUStep的开源版本中,我们找到了直接支持”Block是对象“的证据:
|
|
故我们可以将Block看做是OC对象。