这篇博文继续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的常见错误