block變數儲存域

2021-09-12 17:58:36 字數 2906 閱讀 2461

將block賦值給strong 型別的block變數,或者賦值給strong 修飾的物件型別中的block成員變數時,block會從棧複製到堆上。那__block變數會有什麼變化呢?

其實,當block 被從棧複製到堆上時,block中使用到的變數也會從棧賦值到堆上。

當block被從棧複製到堆前後,__block變數儲存域變化如下:

而如果配置在堆上的block被廢棄,那麼它所使用的__block變數也會被釋放。

從這裡可以看出__block變數的管理,與objective-c的引用計數記憶體管理方式很相似。使用__block變數的block,持有__block變數。如果block被廢棄,它所持有的__block變數也會被釋放。

這裡回顧一下,__block變數內部的__forwarding成員變數作用?

因為__block變數從棧複製到堆,所以在某乙個時刻會有兩個__block變數,如果將棧上的__forwarding指向堆上的__block變數,就可以保證不管你訪問的是棧上的__block變數,還是堆上的__block變數,實際上訪問的都是堆上的__block變數。

這樣,寫法是一致的,而且不管棧上的__block變數是否被釋放,都能通過變數的指標位址正確的訪問到堆上的__block變數。這樣的設計真是非常完美。

當block 中使用__block變數時,__main_block_desc_0結構體內部會多出兩個成員變數copydispose,這兩個成員變數是函式指標型別,裡面分別儲存著兩個靜態函式__main_block_copy_0__main_block_dispose_0

enum

;

__main_block_copy_0函式是將block內使用的__block變數,賦值給目標block用結構體成員變數中,如果是物件型別變數,則持有它。

static

void

__main_block_copy_0

(struct __main_block_impl_0*dst,

struct __main_block_impl_0*src)

_block_object_assign函式當複製的是物件型別變數時,相當於retain例項方法,將物件型別變數賦值在__main_byref_name_1這樣的結構體變數的成員變數中。

__main_block_dispose_0函式內部使用_block_object_dispose函式,來釋放賦值在block結構體中的成員變數。

static

void

__main_block_dispose_0

(struct __main_block_impl_0*src)

_block_object_dispose函式中如果傳的是物件,則相當於release例項方法的函式,如果是非物件,猜測就是普通的釋放變數了。

在clang 轉換出來的c++**中沒有看到呼叫__main_block_copy_0__main_block_dispose_0的地方,據說是在執行時將block從棧複製到堆時以及堆上的block被廢棄時會呼叫這些函式。(這個目前還無法確認)

呼叫copy函式和dispose函式的時機

函式呼叫時機

copy函式

棧上的block複製到堆時

dispose函式

堆上的block被釋放時

在哪些場景下棧上的block會複製到堆上呢?

在這些場景下,block就會被從棧上覆制到堆上。

為什麼在物件中新增block型別的property時,要使用copy修飾符?

其實在arc下,使用strong,retain和使用copy是一樣。

我們都知道,在arc下,使用strong等價於使用retain,而在arc下對block執行retain,會被轉化為objc_blockretain

該函式在runtime中是這樣實現的:

//

// the -fobjc-arc flag causes the compiler to issue calls to objc_

//id objc_retainblock

(id x)

綜上所述,在arc下,對block使用strong等價於使用retain,而對block使用retain,會在執行時呼叫_block_copy,所以這跟使用copy是一樣的效果。

而將block從棧複製到堆上時,可以防止block或者block中使用的變數被釋放。

對block使用copy函式,不管是棧上的、堆上的、全域性的block都不會出現問題。所以,我們就統一使用copy來修飾了。

Block儲存域學習

時間版本修改 2020年5月9日 初稿2020年5月10日 新增編譯器不能自動將block從棧複製到堆上的情況說明 我試圖從網上找一下 objective c高階程式設計 ios與os x多執行緒和記憶體管理 2.3.4節的圖,發現竟然一張都沒找著,本來還想貼一下圖的,本人虎軀一震,一切都變得索然無...

變數儲存域

變數儲存域 2010 09 23 15 43 1.1 變數儲存域 1.1.1 乙個示例 pang123hui首先提供了乙個網上流傳的學習 示例 int a 0 全域性區 void main int b 棧 char s abc s在棧,abc在文字常量區 char p1,p2 棧 char p3 1...

變數儲存型別 作用域

auto 作用域和壽命 只能做區域性變數 在函式內或復合語句內定義的自動變數可以省略auto,而在外部定義的無auto的變數顯然不是自動變數 外部變數,即 全域性變數 的壽命和作用域是全域性的 register 作用域和壽命 同auto,即 區域性可見 分配通用暫存器的條件 1 有空閒的暫存器 2 ...