第十六章 自動引用計數

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")

? ? }

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容