iOS的block記憶體管理

2021-09-07 20:57:43 字數 1191 閱讀 1730

初始情況下:

block本身、__block修飾的變數以及在block內部使用的變數都是在棧裡的。

__block修飾的變數的位址會作為實參傳入block塊內部(暫時先這麼理解,實際比較複雜)。block使用的外部變數被const拷貝到了block內部。也就是block使用的外部變數和這個外部變數本身沒有關係。

copy方法之後

被拷貝的方法還是在棧上。但是拷貝之後的block已經被放在了heap(堆)上。同時__block修飾的變數被移動到了堆上,原來在棧上的已經不存在。還有block的外部變數的const拷貝也被拷貝到了堆上。

如果block塊使用的外部變數是乙個refernce的物件,那麼這個物件的引用計數會增加1。

堆上的block再做一次copy之後,只是引用計數增加1,但是不會重新再做拷貝動作。

retain操作

由於retain是有返回值的。retain要求返回的位址和呼叫物件的位址一致。但是block的位址可能是會變的(尤其是從棧到堆的過程),所以對block做retain操作是沒有用處的。什麼都不會做!

銷毀(或記憶體**時)

heap上的block塊先於stack上的被銷毀時,如呼叫release銷毀堆上的block塊。heap中的block塊在引用計數變為0的時候被銷毀。而__block修飾的變數還在heap中,因為stack還要使用,同時棧上的block快也要使用。

當heap上的block塊晚於stack時,stack會被清除。在heap中的block塊在呼叫release減少引用計數到0的時候釋放記憶體。

block和objective-c物件

如果對block做拷貝操作,block會對其內部使用的物件生成強引用。

如果在block塊內部使用了:

以引用的方式使用了類的成員變數,那麼這個block會對self產生強引用。

以值得方式使用了類的成員變數,那麼這個block會對這個變數本身產生強引用。

例如:

dispatch_async(queue, ^);  

id localvariable =instancevariable;

dispatch_async(queue, ^);

以上可以通過__block修飾符來改變。是的__block是另外的一種儲存型別,就像copy、retain什麼的。這樣這個引用就直接被傳遞到了block中。

但是__block是不可以用來消除對self的迴圈引用的。

iOS關於block的記憶體管理

person person person alloc init int a 20 person.age nsstring stringwithformat d a void myblock2 無引數無返回值的 a 呼叫block myblock 我們在block內部呼叫乙個區域性變數,當我們在呼叫b...

block 記憶體管理

block簡介 copy一段 block作為c語言的擴充套件,並不是高新技術,和其他語言的閉包或lambda表示式是一回事。需要注意的是由於objective c在ios中不支援gc機制,使用block必須自己管理記憶體,而記憶體管理正是使用block坑最多的地方,錯誤的記憶體管理 要麼導致retu...

block的記憶體管理

block的記憶體管理 block變數是儲存在棧記憶體中的,所以宣告屬性時,應該使用copy屬性,將其複製到堆記憶體中。block在dealloc中釋放時,使用函式 block release 假如在customview中宣告了乙個block,在customviewcontroller中建立了乙個c...