第一篇文章 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是指向自身本身的指針。