您的位置:首页 > 其它

ARC环境下循环引用案例

2017-09-24 19:47 295 查看
虽然ARC环境帮助我们做了很多事情,完美的解决了大多数情况下对象的自动释放。但在使用black的情况下,如果不注意,循环引用还是会发生的,导致对象无法释放。

循环引用发生不一定会造成直观的现象,但某些场景下却会带来问题,比如在某个 Controller 注册了 self 为观察者,一般会在 dealloc 中移除观察者。但如果页面无法释放,再次进入这个 Controller 就会重复注册观察者,会出现通知重复调用的问题。

案例一:

[self.model doSomething:^(NSNumber *id) {
self.name = [NSString stringWithFormat:@"我的 id 是%@",id];
}];


上面的代码,self 强引用了 model, model 也强引用了doSomething 这个 block,而 block 的回调中又调用了self 的 name 属性,会导致 block 又强引用了 self,形成循环引用,导致 self 无法释放。

解决办法:

__weak typeof(self) weakSelf = self;
[self.model doSomething:^(NSNumber *id) {
typeof(weakSelf) strongSelf = weakSelf;
strongSelf.name = [NSString stringWithFormat:@"我的 id 是%@",id];
}];


或者

[self.model doSomething:^(NSNumber *id) {
self.name = [NSString stringWithFormat:@"我的 id 是%@",id];
}];
self.model = nil


案例二:

@interface TestViewController ()
{
NSInteger count;
}

@property (nonatomic, strong) TestModel *model;
@end

self.model = [[BHFeiModel alloc] init];
self.model.blockTest = ^{
count = 9;
};


上面的代码乍一看,也没有问题, block 里没有出现 self 。但试验过你会发现,界面依然无法释放。

因为试用 {} 直接声明的,虽然不用 self 进行访问,但实质上和
@property
是一样的,还是会调用 self

因此,改用
@property
声明,然后通过 self 进行访问:

self.model = [[BHFeiModel alloc] init];
__weak typeof(self) weakSelf = self;
self.model.blockTest = ^{
typeof(weakSelf) strongSelf = weakSelf;
strongSelf.imageCount = 9;
};


这样便解决了循环引用导致界面无法释放的问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息