内存的循环引用

内存的循环引用swift

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

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

更严重的是,若是几个对象间接相互引用,好比a<-b b<-c  c<-a 那么a、b、c都没法经过release释放工具

循环引用的场景spa

1、定时器NSTimer代理

2、block的使用调试

3、代理delegate对象

4、父子对象关系(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 选项。

相关文章
相关标签/搜索