美文网首页
Block深层剖析(四)

Block深层剖析(四)

作者: _桃夭大人_ | 来源:发表于2021-01-25 16:04 被阅读0次

    第一篇文章 Block深层剖析(一)介绍了Block的一些基础概念和用法。
    第二篇文章 Block深层剖析(二)分析了最简单的Block源码。
    第三篇文章 Block深层剖析(三) 介绍了Block截获的相关特点和__block说明符。
    这篇文章将会介绍Block存储域和__block存储域。

    通过前面的文章我们知道,Block转换为__main_block_impl_0的结构体类型的自动变量,__block变量转换为__Block_byref_val_0的结构体类型的自动变量。
    结构体类型的自动变量 就是在栈上生成的改结构体类型的实例。

    1.Block存储域

    __main_block_imp_0结构体的成员变量isa的初始化:

    impl.isa = &_NSConcreteStackBlock;
    

    说明该Block的类为_NSConcreteStackBlock类。即Block语法生成的Block为_NSConcreteStackBlock类对象,并且设置对象的存储域在栈上。

    • _NSConcreteStackBlock 设置对象的存储域在栈上

    • _NSConcreteGlobalBlock 设置对象的存储域在数据区

    • _NSConcreteMallocBlock 设置对象的存储域在堆

    Block类的copy操作

    • _NSConcreteStackBlock copy后 从栈复制到堆

    • _NSConcreteGlobalBlock copy后 什么也不做

    • _NSConcreteMallocBlock copy后 引用计数增加

    2.__block存储域

    • 在Block中使用__block变量时,最先将所有的Block配置在栈上,所以__block变量也会配置在栈上。
    • 在Block从栈复制到堆上时,__block变量也会从栈上复制到堆上,并被改Block所持有。
    • 当配置在堆上的Block被废弃,那么它所持有的__block变量也会被释放(在没有持有者的时候才会被释放)。


    3.__forwarding

    __block变量的结构体成员变量__forwarding存在的理由:

    • 无论在Block语法中、Block语法外使用__block变量,都能顺利的访问同一个__block变量。
    • 无论__block变量配置在栈上还是堆上,都能顺利的访问同一个__block变量。

    这是因为:
    当__block变量在栈上时,__forwarding是指向自身本身的指针。

    当__block变量复制到堆上时,会将成员变量__forwarding的值替换为 复制目标堆上的__block变量结构体实例的地址。

    相关文章

      网友评论

          本文标题:Block深层剖析(四)

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