生存周期:自动引用计数

前边铺垫了那么多,现在终于要讲到垃圾回收这个东西了。

ARC

这不是方舟……这是自动引用计数(Automatic Reference Counting),这个东西是苹果用来管理内存的。

它的功能就是那个垃圾堆上的垃圾回收器。它能够保证所有在堆上运行的对象被释放后不会一直驻留在堆上。保证了那块内存会再分配给其他要使用的对象上。

何为释放

说到对象会不会被垃圾回收器给收走,那就要看引用会不会释放了:我们这样来分辨一个对象是否还在被使用——当没有引用再指向某个对象的时候,我们就说它已经被释放了——因为它再也不会被访问到了。

释放的方法

我们一般有三种方法可以释放掉对一个对象的引用:

  • 把引用放在方法里,方法出栈,引用完蛋——对象没了引用,会被回收。
  • 引用更改指向到其他对象上——原本的对象没有了引用,会被回收。
  • 直接清空引用——前提是你声明的储存器是可选类型。

好了,现在我们分别来举几个栗子看:

方法执行完毕出栈,临时变量没了——对象自然就释放掉了。arc 发现对象没有引用了,那么这个对象就会被收回,留下的空间给别人用。

我们吧 gun2 的引用赋给 gun1,那么 gun1原来的引用就被覆盖掉了,那对应的对象也就只能等着被回收啦!

我们重新给 gun1 赋值为空,那么引用没了,对象也就随之完蛋了。

交叉引用

有这么一种情况,会导致自动引用计数捉鸡,我们来看看:

我们稍微修改了刚才的类,增加了一个 Aaa 类的引用属性,然后创建了这个 Aaa 的类,这个类包含了一个 Gun 类的引用属性,这时候我们把它两个互相引用,然后再释放掉……等等,真的可以释放掉吗?

然而并不能。

我们回顾一下一个对象被释放的定义:当对象没有引用就称作被释放——可是这两个对象都还有互相之间的引用呢!

所以,我们虽然访问不到这两个对象了,但是它们两个互相还引用着,arc 无计可施,你一样也不能再访问到它们——这就叫著名的“内存泄露”。

弱引用

这时候,我们要打破这个环路,让引用能够断开,这样才能让这个互相引用的对象一个一个地被释放掉。我们需要将其中一个声明为弱引用,只有这样才能让 arc 断开他们之间的环路。

这样就好了,环路会被打断,泄露的内存也被找回来了。

弱引用的要求

  • 弱引用必须是变量,不能是常量,因为它得可以被修改。
  • 弱引用必须是可选项,它得能被清空。

 

 

“生存周期:自动引用计数”的一个回复

发表评论

电子邮件地址不会被公开。 必填项已用*标注