内存的循环引用
内存的循环引用
吾名蔚 发表于10个月前
内存的循环引用
  • 发表于 10个月前
  • 阅读 21
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

内存的循环引用

在 ARC,开发者将会定义一个变量为“strong”或“weak”。一个 weak 弱引用无法 retain 对象,而 strong 引用会 retain 这个对象,并将其引用计数加一。

循环引用就是指两个对象互相retain对方,通过OBJC的release是无法销毁这两个对象的

更严重的是,如果几个对象间接相互引用,比如a<-b b<-c  c<-a 那么a、b、c都无法通过release释放

循环引用的场景

一、定时器NSTimer

二、block的使用

三、代理delegate

四、父子对象关系(swift)

定时器:

我们在使用NSTimer时经常会作为一个类的属性使用

而NSTimer在初始化的时候回指定self为target.这就造成了self—>NSTimer-->self的循环引用的情况。另外在NSTimer一致处于validata状态时其引用计数器一直是大于0的

解决办法:在不使用定时器以后要调用invalidata移除定时器。

block的使用

block在引用外部的变量是,会对外部变量进行copy操作。在(ARC)模式下会对变量进行强引用,(MRC)模式下变量retainCount加1。当一个类把block作为成员变量时,在block内部使用了这个类本身。造成self—>block-->self或者self-->block-->类的成员变量循环引用的情况。

解决办法:在MRC模式下,在给block赋值时在外部用__blockmySelf = self;用__block修饰使用到的类。

在ARC模式下,用__weak修饰 

代理:

代理协议也是一个典型的场景,需要你使用弱引用来避免循环引用。将代理声明为 weak 是一个即好又安全的做法

父子对象关系

父子对象关系是一个循环引用的典型案例,不幸的是,它也是唯一一个存在于苹果文档中的案例。典型的解决方法就是,在子类定义一个指向父类的变量,声明为 weak 弱引用,从而避免循环引用。

在 swift 中子类指向父对象的变量是一个弱引用,这就迫使我们将该弱引用定义为 optional 类型。如果不使用 optional 可以有另一种做法,将指向父对象的变量声明为“无主引用(unowned)”(表明我们不持有该对象,也不对其进行内存管理)。然而在这种情况下,我们必须非常小心,确保只要还有子对象指向它,父对象不变成 nil,否则会直接闪退。

调试:

使用 Instruments 调试循环引用

XCode 自带了一个很强大的工具 Instruments,用于检测和定位循环引用。一旦你的 app 开发结束,即将提交到 Apple Store,先分析你的 app 是一个好的习惯。Instruments 有很多组件,可以用来分析 app 的不同方面,但是我们现在关心的是 Leak 选项。

标签: 循环引用
共有 人打赏支持
粉丝 2
博文 7
码字总数 3455
×
吾名蔚
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: