Swift ARC 自动引用计数

一、ARC

  • 引用类型在堆上的内存分配过程当中有 8 字节的地址长度用来保存对象的引用计数,堆上的内存并不像栈上那样当即进行回收,系统会定时对堆上的内存进行检查,当某个实例再也不被使用时,引用计数会变为 0,此时系统会自动释放实例所占用的内存空间,一旦释放就不能再访问这个实例的属性和方法。因为该过程是自动的,不须要开发人员来开辟和释放内存,所以称为自动引用计数,简称 ARC(Automatic Reference Counting)。swift

    • 为了不使用中的实例被释放,ARC 会跟踪并计算每个实例被多少属性、常量和变量所引用。
    • 引用有强引用和弱引用之分,这是为了保证在某些循环引用的状况下能够打破循环。
    • 为了保证明例在被属性、常量和变量引用时不会被意外释放,引用默认状况下会被设定为强引用。

1.1 ARC 示例

  • 在构造器和析构器中分别写一个打印语句,用来标示实例的建立和销毁。性能

    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 自己仍会带来一部分性能的损耗,这也解释了为何值类型是更好的选择。变量

相关文章
相关标签/搜索