美文网首页程序员iOS学习
Block的底层实现(二):截获变量的Block

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

作者: 静谧的桔子 | 来源:发表于2017-09-03 21:05 被阅读0次

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

    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

    首先看一下相同的部分,从上面可以看出来__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语法表达式执行时,再赋值给与之前相同表达式的自动变量。

    相关文章

      网友评论

        本文标题:Block的底层实现(二):截获变量的Block

        本文链接:https://www.haomeiwen.com/subject/yfnjjxtx.html