《Objective-C高级编程》Blocks 阅读笔记系列
《Objective-C高级编程》Blocks 阅读笔记 item1(Blocks概要和模式)
《Objective-C高级编程》Blocks 阅读笔记 item2(Block的实质)
《Objective-C高级编程》Blocks 阅读笔记 item3(截获自动变量值)
《Objective-C高级编程》Blocks 阅读笔记 item4(__block说明符)
《Objective-C高级编程》Blocks 阅读笔记 item5(Block存储域)
《Objective-C高级编程》Blocks 阅读笔记 item6(__block变量存储域)
《Objective-C高级编程》Blocks 阅读笔记 item7(截获对象)
《Objective-C高级编程》Blocks 阅读笔记 item8(__block变量和对象)
《Objective-C高级编程》Blocks 阅读笔记 item9(Block循环引用)
《Objective-C高级编程》Blocks 阅读笔记 item10(copy/release实例方法)
2.3 Blocks的实现
2.3.2 截获自动变量值
截获自动变量值的源代码经clang转换,如下:
// 结构体 __block_impl
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
// 结构体 __main_block_impl_0
struct __main_block_impl_0 {
// 成员变量
struct __block_impl impl;
struct __main_block_desc_0* Desc;
const char *fmt; // Block语法表达式“使用的自动变量”被追加到该结构体
int val;
// 构造函数
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags = 0) : fmt(_fmt), val(_val) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
// 静态函数 __main_block_func_0
static void __main_block_func_0(struct __main_block_impl_0 *__cself)
{
const char *fmt = __cself->fmt;
int val = __cself->val;
/*
理解:
1. __main_block_impl_0结构体实例(即Block)所截获的自动变量在Block语法表达式执行之前就被声明定义,所以,在Objective-C的源代码中,执行Block语法表达式时无需改动便可使用截获的自动变量值。
2. "截获自动变量值"意味着在执行Block语法时,Block语法表达式所使用的自动变量值被保存到Block的结构体实例(即Block自身)中。
3. Block不能直接使用“C语言数组类型的自动变量”,所以,截获自动变量时,会将其值传递给结构体的构造函数进行保存
*/
printf(fmt, val);
}
// 静态结构体 __main_block_desc_0
static struct __main_block_desc_0{
unsigned long reserved;
unsigned long Block_size;
} __mian_block_desc_0_DATA = {
0,
sizeof(struct __main_block_impl_0)
};
// 主函数,从这里开始阅读源代码
int main()
{
int dmy = 256;
int val = 10;
const char *fmt = "val = %d\n";
// 调用结构体__main_block_impl_0的构造函数初始化该结构体实例
void (*blk)(void) = &__main_block_impl_0(__main_block_func_0, &__mian_block_desc_0_DATA, fmt, val);
/*
理解:
1. 在初始化结构体实例时,会根据传递给构造函数的参数对由自动变量追加的成员变量进行初始化(即执行Block语法使用的自动变量fmt和val会初始化结构体实例)
2. __main_block_impl_0结构体实例的初始化如下:
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
fmt = "val = %d\n";
val = 10;
3. 由上可知,在__main_block_impl_0结构体实例(即Block)中,自动变量被截获。
*/
return 0;
}
网友评论