Swift 循环引用

1、循环引用

  • 如果两个类互相持有对方的强引用,就会出现循环引用的情况。

2、循环引用示例

  • 比如存在一个学生类,一个班级类,学生类有一个属性叫学生所属的班级,而班级有一个属性是班长,它引用了一个学生类,它们都是可选型。

    class Student {
        var name: String?
        var theClass: Class?
    
        deinit {
            print("Student deinit")
        }
    }
    
    class Class {
        var name: String?
        var classMonitor: Student?
    
        deinit {
            print("Class deinit")
        }
    }
  • 接着我们构造一个学生类实例小明和一个班级类实例三年二班,为了能够销毁对象,把对象声明为可选型,这样在我们不需要对象的时候就可以给它赋值 nil

    var sneb: Class? = Class()
    sneb?.name = "sannianerban"
    
    var xiaoming: Student? = Student()
    xiaoming?.name = "xiaoming"
    
    sneb?.classMonitor = xiaoming
    xiaoming?.theClass = sneb
  • 这时麻烦出现了,根据 ARC 规则,xiaomingsneb 之间互相强引用对方,出现强引用。

  • 在使用完 snebxiaoming 这两个对象后,后面的代码再也不会用到 snebxiaoming 了,此时尝试把这两个变量置为 nil

    sneb = nil
    xiaoming = nil
  • 但是你会发现控制台没有任何打印信息,没有任何一个析构器被调用,这是因为 sneb 和 xiaoming 之间通过属性的方式强引用了对方,二者的引用计数都为 1,ARC 根据规则阻止了实例被销毁,从而造成了内存泄漏。