-
可以.深入研究Block捕獲外部變量和__block實現原理
- 全局變量和靜態全局變量的值改變,以及它們被Block捕獲進去,因為是全局的,作用域很廣
- 靜態變量和自動變量,被Block從外面捕獲進來,成為__main_block_impl_0這個結構體的成員變量
- 自動變量是以值傳遞方式傳遞到Block的構造函數里面去的。Block只捕獲Block中會用到的變量。由于只捕獲了自動變量的值,并非內存地址,所以Block內部不能改變自動變量的值。
- Block捕獲的外部變量可以改變值的是靜態變量,靜態全局變量,全局變量
- Block就分為以下3種
- _NSConcreteStackBlock:只用到外部局部變量、成員屬性變量,且沒有強指針引用的block都是StackBlock。 StackBlock的生命周期由系統控制的,一旦返回之后,就被系統銷毀了,是不持有對象的
- _NSConcreteStackBlock所屬的變量域一旦結束,那么該Block就會被銷毀。在ARC環境下,編譯器會自動的判斷,把Block自動的從棧copy到堆。比如當Block作為函數返回值的時候,肯定會copy到堆上
- _NSConcreteMallocBlock:有強指針引用或copy修飾的成員屬性引用的block會被復制一份到堆中成為MallocBlock,沒有強指針引用即銷毀,生命周期由程序員控制,是持有對象的
- _NSConcreteGlobalBlock:沒有用到外界變量或只用到全局變量、靜態變量的block為_NSConcreteGlobalBlock,生命周期從創建到應用程序結束,也不持有對象
- _NSConcreteStackBlock:只用到外部局部變量、成員屬性變量,且沒有強指針引用的block都是StackBlock。 StackBlock的生命周期由系統控制的,一旦返回之后,就被系統銷毀了,是不持有對象的
ARC環境下,一旦Block賦值就會觸發copy,__block就會copy到堆上,Block也是__NSMallocBlock。ARC環境下也是存在__NSStackBlock的時候,這種情況下,__block就在棧上
ARC下,Block中引用id類型的數據有沒有__block都一樣都是retain,而對于基礎變量而言,沒有的話無法修改變量值,有的話就是修改其結構體令其內部的forwarding指針指向拷貝后的地址達到值的修改
更多:iOS面試題合集