- 定义:循环引用可以简单理解为A引用了B,而B又引用了A,双方都同时保持对方的一个引用,导致任何时候引用计数都不为0,始终无法释放;
- 造成循环引用的三种情况
- 计时器NSTimer
- 原因分析:
- NSTimer变量通过target对xxxModel有强引用,NSTimer变量是xxxModel内部的成员变量,所以xxxModel对该成员变量有强引用
- 解决办法:
- 提供类似cleanTimer的公开方法,让外界主动调用释放NSTimer变量
- 原因分析:
- block
- 原因分析:
- 某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了self的成员,因为直接在block使用self的成员,这样block内部就会对self进行强引用,导致循环引用
- 只要你在block里用到了self的成员,就会出现循环引用,并不需要显式地出现self,block的这种循环引用会被编译器捕捉到并及时提醒
- 解决办法:
- (1)构建一个weakSelf,通过这种方式告诉block,不要在block内部对self进行强制strong引用
// ARC环境:使用__weak关键字 __weak typeof(self) weakSelf = self; // MRC环境:使用__block关键字 __block typeof(self) weakSelf = self;
- (2)再将weakSelf在block中使用,就不会造成循环引用
- (1)构建一个weakSelf,通过这种方式告诉block,不要在block内部对self进行强制strong引用
- 原因分析:
- delegate
- 原因分析:
- 如果将代理设置为强应用,那么控件就会对它的使用者有一个强引用,由于控件的使用者对控件已经产生强引用,这样就会造成循环引用
- 解决办法:
- 声明delegate时请用assign(MRC环境)或者weak(ARC环境),千万别手贱玩一下retain或者strong,毕竟这基本逃不掉循环引用了
- 原因分析:
- 计时器NSTimer
示例代码:OC常见的循环引用示例
时间: 2024-11-13 00:43:18