Block与外部变量

2020-11-07  本文已影响0人  一个半吊子工程师

一、截获自动变量(局部变量)值

默认情况

对于block 外的变量引用,block默认是将其复制到自身的数据结构中来实现访问的;
也就是说,block的自动变量截获只针对block内部使用的自动变量,不使用则不截获;
截获的自动变量会存储于block的结构体内部,这会导致block的体积变大
特别要注意的是默认情况下block只能访问不能修改局部变量的值

    int age = 10;
    void (^block)(void) = ^{
        NSLog(@"age = %d",age);
    };
    age = 18;
    block();
输出结果

__block修饰的外部变量

对于用__block 修饰的外部变量引用,block是 复制其引用地址来实现访问的;
block可以修改__block修饰的外部变量的值

image.png
__block int age = 10;
        void (^block)(void) = ^{
            NSLog(@"age = %d",age);
        };
        age = 18;
        block();
输出结果

为什么使用__block修饰的外部变量的值就可以被block修改呢?
我们使用clang 将 OC代码转换为C++文件:

// cd 文件路径
clang -rewrite-objc 源代码的文件名
image.png
会发现一个局部变量加上__block修饰符后将会和block一样变成一个__Block_byref_age_0结构体类型的自动变量实例;
我们在block内部访问age变量则需要通过一个叫__forwarding的成员变量来间接访问age变量
(age.__forwarding->age) = 18;
上一篇 下一篇

猜你喜欢

热点阅读