美文网首页iOS开发
iOS 循环引用导致内存泄漏

iOS 循环引用导致内存泄漏

作者: BlackStar暗星 | 来源:发表于2020-03-08 20:07 被阅读0次

首先我们需要先了解什么是循环引用

  • 循环引用
    简单来说循环引用就是 A持有B B持有C C持有A ,因为相互持有,导致无法单独释放某一类的内存 。我们以Block回调为例
[self.singleton.singleBlock = ^(NSString * _Nonnull des) {
    self.myName = des;
};

self 持有 singleton , singleton持有Block, Block持有 self ,也可直接理解为 self 持有 singleton , singleton 持有 self,当self需要释放的时候,singleton是不需要释放的,但是 singleton 持有self 导致 self 不能被释放,因此,self 无法被释放,导致内存泄漏。


其次我们需要了解那些常见的操作会造成内存泄漏,为什么会造成内存泄漏,而我把这些操作大致归为两类

一、Block 回调造成的循环引用
二、NSTimer

一、Block 回调造成的循环引用

  • 网络使用 block 回调强持有self造成的循环引用
    现在对于网络的回调大多数采用两种方式回调:delegate & block
    而大多数使用AFNetworking的时候,通常采用 block 进行回调,block 强持有 self 从而造成 循环引用,最终导致内存泄漏。

  • 其他自定义类使用 block ,和网络一样

  • UITableViewCell cell 使用block ,为什么cell也会造成循环引用呢,因为self 持有tableview ,而 tableview 对 cell 其实是一种强持有的关系,所以在cell使用block的时候,也会造成循环引用

  • 单例 使用 block 强持有 self
    我们都知道单例一旦被创建,整个应用的声明周期都只会创建者一次,而且在应用的寿命周期结束之前是不会被释放的,那么如果单例使用 block 并且 在 block 回调内调用了 self ,那么此 单例 就强持有了 self,而 单例 不会释放,就造成了self无法释放,从而造成内存泄漏

二、NSTimer 强持有self

  • NSTimer
    timer 为什么会造成内存泄漏,首先我们看 timer 的使用
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];

我们发现: timer 的 target 是 self ,其实这一操作是对 self 的强引用,当页面将要释放的时候,由于 timer 强持有 self 从而导致 self 无法被释放,这就导致了内存泄漏。

注意:如果你觉得 只要在 dealloc 里 去结束 timer ,那你就想错了,因为他们的关系是必须 timer 先结束 dealloc 才会被调用,所以我们是不能在 dealloc 里 调用timer的 invalidate 方法的, 切记、切记


解决办法,使用 __weak typeof(self)weakSelf = self; 弱化self,打破循环引用(必要的时候我们还需要在block内部声明 strongSelf ,为防止weakSelf因为某种原因在block里提前释放使得weakSelf=nil,变成野指针,导致后边再调用weakSelf 造成崩溃)。示例如下

__weak typeof(self)weakSelf = self;
[singleton shareSingleton].singleBlock = ^(NSString * _Nonnull des) {
   weakSelf.myName = des;
};

相关文章

  • iOS 循环引用导致内存泄漏

    首先我们需要先了解什么是循环引用 循环引用简单来说循环引用就是 A持有B B持有C C持有A ,因为相互持有,导致...

  • Swift中Weak References弱引用和Unowned

    循环引用 循环引用在iOS开发中是需要非常重视的一个问题,不合理的循环引用会导致内存的泄漏,这在开发中是非常危险的...

  • 循环引用导致内存泄漏

    前言 由循环引用导致的内存泄漏是常出现的一个原因。一般都是weak给弱化一方的指针,打破循环引用。一些隐藏的循环引...

  • block的循环引用

    什么是循环引用呢? 就是我引用你,你引用我,就会造成循环引用,双方都不会被销毁,导致内存泄漏。 _block = ...

  • NSTimer 循环引用问题

    题记 在iOS 10系统之前,系统的NSTimer是会引起循环引用的,导致内存泄漏。下面就针对这个问题给出几种解决...

  • 循环引用

    由于iOS采用的引用计数,来管理内存,如果相互强引用持有,则无法释放,从而造成内存泄漏。 避免循环引用的规则 1、...

  • ARC模式下的循环引用引起内存泄漏

    ARC模式下的循环引用引起内存泄漏 ​ 自从iOS 5时代自动引用计数(Automatic Reference...

  • iOS内存优化

    引起内存泄漏的原因 引起内存泄漏的原因主要有三类,如下 循环引用 强引用 非OC对象 1、循环引用。最简单的循环引...

  • IOS循环引用、内存泄漏、野指针

    一、循环引用和内存泄漏 1、block循环引用 分析:因为WGBlockTestViewController强引用...

  • 循环强引用

    循环强引用会导致内存泄漏内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法...

网友评论

    本文标题:iOS 循环引用导致内存泄漏

    本文链接:https://www.haomeiwen.com/subject/cxpvrhtx.html