Objective-C的Block实质与实现探究 part-3

Block截获静态变量的情况



要使得Block能够改变值的第一种办法,是使用静态变量、静态全局变量、全局变量三种之一。下面的例子会使用到这三种变量。

Objective-C:

int global_val = 1;
static int static_global_val = 2;

int main() {
    static int static_val = 3;
    
    void (^blk)(void) = ^{
        global_val *= 1;
        static_global_val *= 2;
        static_val *= 3;
    };
    return 0;
}

C++源码:

int global_val = 1;
static int static_global_val = 2;
struct __main_block_impl_0 {
    struct __block_impl impl;
    struct __main_block_desc_0 *Desc;
    int *static_val;
    
    __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_static_val, int flags=0) : static_val(_static_val) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
    }
};

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
    int *static_val = __cself->static_val;

    global_val *= 1;
    static_global_val *= 2;
    (*static_val) *= 3;
}

static struct __main_block_desc_0 {
    unsigned long reserved;
    unsigned long Block_size;
} __main_block_desc_0_DATA = {
    0,
    sizeof(struct __main_block_impl_0)
};

int main() {
    
    static int static_val = 3;
    
    blk = &__main_block_impl_0(__main_block_func_0, &__main_block_desc_0_DATA, &static_val);

    return 0;
}
Objective-C的Block实质与实现探究 part-3_第1张图片
Block数据结构图(5)

这里涉及到作用域,碍于篇幅只作简要说明:全局变量和静态全局变量在这个例子中是一样的,都能够被Block的实现代码访问到,但是静态变量不能。那么Block如何解决这个问题呢?最简单的当然是指针了。

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
    int *static_val = __cself->static_val;

    (*static_val) *= 3;
}

使用静态变量的指针对其进行访问。将静态变量static_val的指针传递给__main_block_impl_0结构体的构造函数并保存。这是超出作用于使用变量最简单的方式。注意:这里只截获静态变量,全局变量和静态全局变量不需要截获,因其作用域,在代码块内也可以访问。

你可能感兴趣的:(Objective-C的Block实质与实现探究 part-3)