内存泄漏与循环引用
2020-07-27 本文已影响0人
落叶兮兮
在iOS开发中,内存泄漏是让开发者比较头疼的一件事。虽然ARC可以帮助开发者解决大部分的内存管理问题,但其对内存泄漏依旧束手无策。
内存泄漏的核心问题是循环引用。什么是循环引用?在Objective-C设计中,对象会对其内的属性进行持有,当一个对象的引用计数为0,将其内存回收时,这个对象会向其中所有的属性发送release消息,让其中的属性对象进行释放。

如果对象内的某个属性再次对当前对象进行了持有,则会产生循环引用,因为对象只有在引用计数降为0时,才会向其内的属性发送release消息。同样,只有其内属性接收到了release消息时,才会对它们所持有的所有对象进行了释放,当前对象的引用计数才有可能降为0,此时就产生了循环引用。

在开发中,引起循环引用的情况主要是以下三种情况:
block与循环引用
下面的代码就会产生循环引用
self.myBlock = ^BOOL(int param) {
NSLog(@"%@",self);
return YES;
}
在Block中使用外部的对象时,都会对对象进行一次强引用,因此上面的代码会产生循环引用。因为myBlock是当前类中的属性,所以当前类对象会对myBlock有强引用,只有当当前类对象引用计数被降为0时,才会对myBlock发送release消息,同样,由于在myBlock内部使用到了self关键字,使得myBlock又对当前类对象进行了强引用,当前类对象要想释放,必须等myBlock对象的引用计数降为0,这就产生了内存泄漏。
解决办法就是在block中使用弱引用的指针即可。
__weak typeof(self) __self = self;
self.myBlock = ^BOOL(int param) {
NSLog(@"%@",__self);
return YES;
}
代理与循环引用
这个delegate的属性设置为strong时就会产生,解决办法就是将其设置为weak,这也是为什么我们使用delegate时使用weak修饰的原因,就是为了避免循环引用