弱引用(weak)
声明属性或者变量时,在前面加上weak关键字表明这是一个弱引用,弱引用会被定义为可选类型变量,而不是常量,因为定义的类型可以被赋值为nil。
案例
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
deinit { print("\(name) is being deinitialized") }
}
class Apartment {
let unit: String
init(unit: String) { self.unit = unit }
weak var tenant: Person?
deinit { print("Apartment \(unit) is being deinitialized") }
}
建立两个变量(john和unit4A)之间的强引用,并关联两个实例:
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
两个关联在一起的实例的引用关系如下图所示:
Person
实例依然保持对Apartment
实例的强引用,但是Apartment
实例只持有对Person
实例的弱引用。这意味着当你断开john
变量所保持的强引用时,再也没有指向Person
实例的强引用了:
由于再也没有指向Person
实例的强引用,该实例会被销毁:
john = nil
// 打印 “John Appleseed is being deinitialized”
唯一剩下的指向Apartment实例的强引用来自于变量unit4A。如果你断开这个强引用,再也没有指向Apartment实例的强引用了:
由于再也没有指向
Apartment
实例的强引用,该实例也会被销毁:
unit4A = nil
// 打印 “Apartment 4A is being deinitialized”
上面的两段代码展示了变量john
和unit4A
在被赋值为nil
后,Person
实例和Apartment
实例的析构函数都打印出“销毁”的信息。这证明了引用循环被打破了。
注意
在使用垃圾收集的系统里,弱指针有时用来实现简单的缓冲机制,因为没有强引用的对象只会在内存压力触发垃圾收集时才被销毁。但是在 ARC 中,一旦值的最后一个强引用被移除,就会被立即销毁,这导致弱引用并不适合上面的用途。