美文网首页iOS
iOS - block原理解读(三)

iOS - block原理解读(三)

作者: tigerAndBull | 来源:发表于2019-02-22 17:56 被阅读0次

    前言

    在阅读该篇文章前,推荐阅读
    ios - block原理解读(一)
    ios - block原理解读(二)

    本文解决问题

    • __block原理
    • copy函数,从栈copy到堆的过程(同对象变量)

    __block原理

    通过__block修饰的自动变量,可以在block内部进行值修改。

    typedef void (^Block)(void);
    Block block;
    
    int main(int argc, char * argv[]) {
        @autoreleasepool {
            
            __block int a = 10;
            
            block = ^{
                a++;
            };
            
            return 0;
        }
    }
    

    将代码编译成C++源码

    // 原代码
    __block int a = 10;
    // c++源码
    __attribute__((__blocks__(byref))) __Block_byref_a_0 a = {
        (void*)0,
        (__Block_byref_a_0 *)&a, 
        0, 
        sizeof(__Block_byref_a_0), 
        10
    };
    

    可以看到 变量a 变成了 结构体类型__Block_byref_a_0

    下面再看看结构体__Block_byref_a_0的构造

    struct __Block_byref_a_0 {
      void *__isa;
    __Block_byref_a_0 *__forwarding;
     int __flags;
     int __size;
     int a;
    };
    

    通过上面结构体的初始化和结构体的构造,
    可以获得以下信息:

    1. __forwarding存放的是自己本身的地址
    2. 结构体内的a变量存放的是外部变量a的值

    主结构体__main_block_impl_0的变化

    image.png image.png

    首先说明一点,
    在block初始化过程中,有一个由栈block指向堆block的过程。

    一开始,栈空间的block有一个__Block_byref_a_0结构体,
    指向外部__Block_byref_a_0的地址,
    其中它的__forwarding指针指向自身,

    当block从栈copy到堆时,

    堆空间的block有一个__Block_byref_a_0结构体,
    指向外部__Block_byref_a_0的地址,
    其中它的__forwarding指针指向自身(复读机)

    如何从栈指向堆,并建立联系呢?

    apple源码,如图:


    copy函数相关源码.png

    copy->forwarding = copy;
    就是将堆结构体的__forwarding指针指向自身
    src->forwarding = copy;
    就是将栈结构体的__forwarding指针指向堆结构体

    这样,苹果工程师在背后悄悄地将block copy到了堆上,
    而且栈上的block从未被我们利用过。

    在看看block入口静态函数

    static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
      __Block_byref_a_0 *a = __cself->a; // bound by ref
      (a->__forwarding->a)++;
    }
    

    通过当前栈空间主结构体上的__Block_byref_a_0结构体指针,访问指向堆空间的__forwarding成员,并获取堆空间上变量的值。

    当然,不仅__block修饰的变量会这样,前文的对象类型变量同样会在copy函数内部被转化成类似的结构体进行处理。

    相关文章

      网友评论

        本文标题:iOS - block原理解读(三)

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