Block
简单的block
int main() {
void (^blk)(void) = ^{printf("Block\n");};
blk();
return 0;
}
会被编译器编译成下面那样
// 编译器编译后 准备工作
// 生成一个block结构体,本身信息和捕获的变量
struct _main_block_desc_0 {
uintptr_t reserved;
uintptr_t size;
};
struct _block_impl {
void *isa; &_NSComcreteStackBlock 三类
int flags; // contains ref count
int reserved;
void *FuncPtr;
};
struct _main_block_impl_0 {
struct _block_impl impl;//存储block基本信息和闭包函数指针
struct Block_descriptor_1 *descriptor; //存储block大小
// 捕获的参数
...
...
}
// 初始化 Block 描述结构体_main_block_desc_0,得到block大小
static _main_block_desc_0_DATA = _main_block_desc_0{0,sizef(_main_block_impl_0) }
// block内实现被编译器转换成函数,参数是block结构体
static void _main_block_func_0(struct _main_block_impl_0 *_cself){
Block内实现
}
// 正式开始
int main() {
// 局部指针变量,指向 _main_block_impl_0结构体。 传入准备好的描述和实现
// _main_block_impl_0结构体实例的指针赋给变量blk。该源代码中的Block就是_main_block_impl_0
// 结构体类型的自动变量,即栈上生成的_main_block_impl_0结构体实例
blk = _main_block_impl_0(_main_block_func_0, &_main_block_desc_0_DATA)
// 执行
(*blk->impl.FuncPtr)(blk)
return 0;
}
block即对象
Block编译后可以看到是由C语言的结构体实现的,Blcok的实现跟OC中对象的实现是类似的。在OC中,凡是第一地址是isa指针都被认为是对象,block符合。
网友评论