swift用自动引用计数(ARC)机制来对引用类型进行内存管理,(包括类实例和闭包)。
自动引用计数会引入循环强引用的问题。
解决循环强引用的办法是弱引用和无主引用,分别用关键字weak和unknown来标示。
两个类实例互相持有对方的强引用,因而每个实例都让对方一直存在。
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 }
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
print(john?.apartment?.unit)
print(unit4A?.tenant?.name)
john = nil
unit4A = nil
john和unit4A的析构器都没有被调用。
解决办法是将类Apartment的var tenant: Person?设成弱引用weak var tenant: Person?
闭包引起的循环强引用
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: (Void) -> String = {
[unowned self] in
if let text = self.text {
return "<\(self.name)>\(text)"
} else {
return "<\(self.name) />"
}
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) is being deinitialized")
}
}