block
是在棧上生成的,所以一般使用copy
方法把block
複製到堆上,避免block
被立刻釋放。
block
會對內部的變數形成強引用,而如果同時該變數又持有這個block
,就會導致迴圈引用而無法釋放,從而導致記憶體洩露。
最常見的就是self
持有block
,而又在block
內部呼叫self
的方法或屬性,那self
和block
就會形成迴圈引用而無法釋放。由於我們習慣在dealloc
中釋放物件,但是即使在dealloc
中將block
釋放也沒用,因為self
的dealloc
根本不會跑進去。比如:
1 self.myblock = ^void();
其實,最簡單的解決方法就是在self
的某個非dealloc
方法中將block
主動釋放,並在需要釋放self
之前呼叫這個方法,這樣才能有效的解除引用。但是這種方法使用起來比較麻煩,而且很容易忘記呼叫。
所以我們一般是在block
中使用弱引用的self
。下面分別介紹arc
和mrc
中在block
中使用弱引用self
的方法。
1 __weak typeof(self) weakself =self;23 self.myblock = ^void
();
這樣做的好處是不必在block
直接使用self
,這樣就不會對self
進行強引用,只要self
需要釋放,self
就會自動釋放,block
也會自動釋放。在arc
中,進入block
前,需要使用__weak
對self
進行弱引用,並在block
中使用__strong
對weakself
進行強引用。
這樣做的另乙個好處是,在arc
中使用__weak
之後,如果self
在某個地方被釋放了,那weakself
也會被自動置為nil
,這樣即使在block
中使用weakself
,也不會訪問錯誤。
而在block
中使用__strong
則是為了避免在使用block
的過程中self
被釋放導致訪問出錯。
1 __block typeof(self) blockself =self;
23 self.myblock = ^void
();
其實,mrc
的基本思路和arc
是一樣的。有兩處不同:
在mrc
中使用__block
而不是__weak
進行弱引用,因為在arc
中使用__block
會對該物件進行強引用。
在mrc
的block
中使用malloc_zone_from_ptr()
方法判斷blockself
是否已經被釋放,因為mrc
不會對已釋放的物件自動置為nil
。
可見,無論是mrc
還是arc
,解決方法都是類似的。雖然block
的使用增加了簡潔性和便利性,但使用block
的過程中也要時刻注意避免記憶體洩露。
how do i declare a block in objective-c? 總結了宣告block
的幾種格式,在開發過程中可以參考使用。
block 迴圈引用
結論 block作為成員變數,內部引用self的成員變數,必須使用self 弱引用 block作為區域性變數,無論怎樣寫,都不會對self造成強引用 block為變數 1 block為成員變數 typedef nsstring blockcc void inte ce twoviewcontroll...
block迴圈引用
底層原始碼 typedef void ghblock void struct main block impl 0 static void main block func 0 struct main block impl 0 cself static void main block copy 0 st...
BLOCK迴圈引用
何時block才會迴圈引用 為什麼block會迴圈引用 我們很多行為會導致block的copy,而當block被copy時,會對block中用到的物件產生強引用 arc下 或者引用計數加一 mrc下 如下 property nonatomic,readwrite,copy completionblo...