<aside> 💟 当一个实例的生命周期较短,或者互相引用的两个实例都可被置空时,对其引用可以使用弱引用,而当一个实例的生命周期较长,即使引用它的实例都销毁了它仍然存在,或者一个可以被置空而另一个不可时,使用无主引用。
</aside>
<aside>
🌟 因为被弱引用的实例可能会被 ARC
置空,所以声明时一般要用变量,且为可选项。
</aside>
<aside>
🌰 当弱引用被 ARC
置空时,属性观察器不会被触发。
</aside>
/**
弱引用
*/
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") }
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
// 打印“John Appleseed is being deinitialized”
unit4A = nil
// 打印“Apartment 4A is being deinitialized”
/**
无主引用
*/
var greeting = "Hello, playground"
class Customer {
let name: String
var card: CreditCard?
init(name: String) {
self.name = name
}
deinit { print("\\(name) is being deinitialized") }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) {
self.number = number
self.customer = customer
}
deinit { print("Card #\\(number) is being deinitialized") }
}
var john2: Customer?
john2 = Customer(name: "John2 Appleseed")
john2!.card = CreditCard(number: 1234_5678_9012_3456, customer: john2!)
john2 = nil
// 打印“John Appleseed is being deinitialized”
// 打印“Card #1234567890123456 is being deinitialized”
<aside>
🧀 可选类型 Optional
是一个枚举,虽然如枚举、结构体这样的值类型不能被标记为 unowned
,因为自动引用计数是针对引用类型的内存管理,但是可选类型是个例外。
且可选值内包装的类不使用自动引用计数,所以不需要维持对可选值的强引用。
</aside>
class Department {
var name: String
var courses: [Course]
init(name: String) {
self.name = name
self.courses = []
}
}
class Course {
var name: String
unowned var department: Department
unowned var nextCourse: Course?
init(name: String, in department: Department) {
self.name = name
self.department = department
self.nextCourse = nil
}
}
let department = Department(name: "Horticulture")
let intro = Course(name: "Survey of Plants", in: department)
let intermediate = Course(name: "Growing Common Herbs", in: department)
let advanced = Course(name: "Caring for Tropical Plants", in: department)
intro.nextCourse = intermediate
intermediate.nextCourse = advanced
department.courses = [intro, intermediate, advanced]
<aside> 🥞 当相互引用的两个实例都不可为空时,一个类使用无主引用声明另一个类,另一个类使用隐式解包可选项的方式引用前一个类。
</aside>
class Country {
let name: String
var capitalCity: City!
init(name: String, capitalName: String) {
self.name = name
self.capitalCity = City(name: capitalName, country: self)
}
}
class City {
let name: String
unowned let country: Country
init(name: String, country: Country) {
self.name = name
self.country = country
}
}
var country = Country(name: "Canada", capitalName: "Ottawa")
print("\\(country.name)'s capital city is called \\(country.capitalCity.name)")
// 打印“Canada's capital city is called Ottawa”