Block的底层实现(二):截获变量的Block

接着上一篇接下来,添加一下参数看看

int main(){
 int dmy = 256;
 int val = 10; 
 const char *fmt = "val = %d\n"; 
 void (^blk)(void) = ^{ printf(fmt,val); }; 
 val = 2;
 fmt = "These value were changed. val = %d\n";
 blk();
 return 0;
}

通过之前的clang命令编译一下,得到以下的代码


屏幕快照 2017-08-25 下午10.20.03.png

屏幕快照 2017-08-25 下午10.20.03.png

首先看一下相同的部分,从上面可以看出来__main_block_desc_0和__block_impl是相同,然后看一下不同的地方__main_block_impl_0的声明以及初始化;声明部分可以看到,之前使用的自动变量通过block语法作为成员变量追加到__main_block_impl_0结构体中,__main_block_impl_0结构体的成员变量类型的声明与自动变量的类型完全相同。注意,Block语法表达式中没有用到的自动变量不会被追加。下面是初始化该结构体实例的构造函数的差异:

__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags=0) : fmt(_fmt), val(_val)

在初始化结构体实例时,根据传递给构造函数的参数对由自动变量追加的成员变量进行初始化。接下里时使用Block的匿名函数的实现。

static void __main_block_func_0(struct __main_block_impl_0 *__cself) { const char *fmt = __cself->fmt; // bound by copy int val = __cself->val; // bound by copy printf(fmt,val); }

之前声明定义的__main_block_impl_0结构体实例的成员变量的自动变量被使用到了Block语法表达式中。总的来说,截获到的自动变量作为成员变量被追加到__main_block_impl_0结构体中,在Block语法表达式执行时,再赋值给与之前相同表达式的自动变量。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容