這篇博文繼續block的常見錯誤——循環引用。程序員
循環引用是不少初學者不能察覺的,其產生的緣由,是block中的代碼會對對象進行強引用。數組
讀者請閱讀示例代碼1,並思考示例代碼1所建立的對象可否被正常銷燬?xcode
示例代碼1:atom
* mark 將代碼改成調用self的方法 -(NSMutableArray * (_myBlocks ===-=(^sum)(, ) = ^( x, mark 對象被釋放時自動調用 - (
結果是不能正常釋放的。讀者不妨在xcode中試試。spa
產生緣由在block代碼中出現了self:code
int(^sum)(int, int) = ^(int x, int y) { return [self sum:x y:y]; };
此時sum的block對self強引用,在加上self對myBlocks強引用:orm
@property (nonatomic, strong) NSMutableArray *myBlocks;
以及sum block被添加到數組時,會被數組強引用:對象
[self.myBlocks addObject:sum];
這三個引用之間造成了循環引用,以下圖:it
循環引用的結果就是對象沒法被釋放!table
碰到這類問題,程序員如何解除循環引用呢?
有如下幾種解決方案:
1.在block代碼中不要引用self以及其餘局部變量;如
int(^sum)(int, int) = ^(int x, int y) { return [self sum:x y:y]; };
修改爲
int(^sum)(int, int) = ^(int x, int y) { return x + y; };
2.使用__weak關鍵字,能夠將局部變量聲明爲弱引用
如:
- (instancetype)init { self = [super init]; if (self) { int(^sum)(int, int) = ^(int x, int y) { return [self sum:x y:y]; }; [self.myBlocks addObject:sum]; } return self; }
修改成:
- (instancetype)init { self = [super init]; if (self) { __weak DemoObj *weakSelf = self; int(^sum)(int, int) = ^(int x, int y) { return [weakSelf sum:x y:y]; }; [self.myBlocks addObject:sum]; } return self; }
block的循環引用就說到這,下一篇繼續來說解block的常見錯誤