引用类型在堆上的内存分配过程当中有 8 字节的地址长度用来保存对象的引用计数,堆上的内存并不像栈上那样当即进行回收,系统会定时对堆上的内存进行检查,当某个实例再也不被使用时,引用计数会变为 0,此时系统会自动释放实例所占用的内存空间,一旦释放就不能再访问这个实例的属性和方法。因为该过程是自动的,不须要开发人员来开辟和释放内存,所以称为自动引用计数,简称 ARC(Automatic Reference Counting)。swift
在构造器和析构器中分别写一个打印语句,用来标示实例的建立和销毁。性能
class Student { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age print("建立了一个实例") } deinit { print("销毁了一个实例") } }
声明两个变量,把它们的类型声明为 Student
的可选型,如今它们尚未被赋值。优化
var xiaoming: Student? var xiaogang: Student?
经过构造器建立一个 Student
的实例,而后把这个实例赋值给第一个变量。code
xiaoming = Student(name: "xiaoming", age: 12)
此时运行程序输出以下。对象
建立了一个实例
此次让第二个变量也引用这个实例,如今这个实例的引用计数为 2,表明着 Student
实例的内存地址被引用了两次。内存
xiaogang = xiaoming
下面经过给变量赋值 nil
来断开引用,首先断开一个变量的引用,如今 Student
实例的引用计数已变为 1。开发
xiaogang = nil
接着断开第二个变量的引用,如今没有任何属性或者变量引用这个实例了。it
xiaoming = nil
能够看到中控台打印信息以下,这个类调用了析构器,表明它被销毁了,释放出了实例所占用的内存空间。class
销毁了一个实例
看起来只是引用的数量增减那么简单,不过在真实的内存中,ARC 在检验某个对象的计数时不可避免的须要对堆内存进行加锁和解锁处理,也就是说不管你如何在代码层面优化代码,ARC 自己仍会带来一部分性能的损耗,这也解释了为何值类型是更好的选择。变量