最近越来越发现循环引用的严重性,总结一些已经遇到的场景,提升防引用意识。
1. UIViewController型
- 描述
伪代码如下:
// 后台监听方法
- (void)appWillEnterBackGround(){
[self.draftHandler saveToSandBox]; //保存数据到沙盒中
}
// 循环引用发生方法
- (void)fun1{
AManager *manager = [manager initWithParam:(id)param completion:^(id param1, id param2){
[self fun2];
];
self.manager = manager;
}
- (void)fun2{}
场景:在操作完成清理一条数据后,app 进入后台,重新进入app出现多一条数据
- 分析
由于func1里的循环引用,导致self无法释放,当清理完数据库一条数据后,App进入后台,触发了后台监听方法,导致清理的数据重新保存,所以此情况下数据一直清理不掉。
- 解决 fun1里使用__weak
- 引申
其实,即使fun1里没有self.manager = manager,也可能会触发此问题,这时并不是因为循环引用,而是manager的block里强引用了self,延长了self的生命周期,所以当block未执行完毕时,self依然不会释放。在这个场景里,block应该使用weakSelf最好。
关于block要考虑得问题:
- 循环引用,可能导致对象不释放
- block内部引用,可能延长对象生命周期
// TODO:遇到典型的继续更新