Block深层剖析(四)

第一篇文章 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深层剖析(四))