block的copy和循環引用的問題

在實際開發中,發現使用Block有着比delegate和notification更簡潔的優勢。於是在目前的項目中大量的使用block。 

 在我的頭文件我是這樣聲明使用block的。

 @interface BrushViewController : BaseViewController 

 @property (nonatomic, copy) void (^getCardInfo)(NSDictionary *cardInfo); 

 @end 

我將block聲明爲copy的原因是在代碼塊裏面我可能會使用一些本地變量。而block一開始是放在棧上的,只有copy後纔會放到堆上。

如果不加copy屬性,當其所在棧被釋放的時候,這些本地變量將變得不可訪問。一旦代碼執行到block這段就會導致bad access。

brush.getCardInfo=^(NSDictionary *info){ 

 [self test]; 

 }; 

像上面這段代碼,self其實是一個本地變量而不是block內部變量,如果聲明爲assign,代碼執行到block內部就會出錯。但是這又帶來另一個問題,就是self的引用計數+1。這意味着很可能會導致循環引用。self持有brush,brush持有block,block持有self。結果就是內存泄漏。

解決的辦法如下:

 __block CurrentViewController* blockSelf = self; 

 brush.getCardInfo=^(NSDictionary *info){

 [blockSelf test]; 

 }; 

通過這個方式,告訴block這個變量的引用計數不要+1。如果你使用的是ARC,那麼就應該改成下面這樣:

 __weak CurrentViewController* blockSelf = self; 

 brush.getCardInfo=^(NSDictionary *info){

 [blockSelf test];

 };

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章