Swift中的循环强引用 【使用无主引用解决】
無主引用(unowned)
聲明屬性或者變量時,在前面加上unowned關鍵字表示這是一個無主引用,無主引用不能設置為nil,因為非可選類型的變量不允許被賦值為nil。
兩個屬性,其中一個為可選類型,另外一個不是可選類型,而且相互引用,這種情況下一般使用無主引用去解決循環強引用。
案例
class Customer {let name: Stringvar card: CreditCard?init(name: String) {self.name = name}deinit { print("\(name) is being deinitialized") } } 復制代碼class CreditCard {let number: UInt64unowned let customer: Customerinit(number: UInt64, customer: Customer) {self.number = numberself.customer = customer}deinit { print("Card #\(number) is being deinitialized") } } 復制代碼注意 CreditCard類的number屬性被定義為UInt64類型而不是Int類型,以確保number屬性的存儲量在 32 位和 64 位系統上都能足夠容納 16 位的卡號。
下面的代碼片段定義了一個叫john的可選類型Customer變量,用來保存某個特定客戶的引用。由于是可選類型,所以變量被初始化為nil: var john: Customer?
現在你可以創建Customer類的實例,用它初始化CreditCard實例,并將新創建的CreditCard實例賦值為客戶的card屬性:
john = Customer(name: "John Appleseed") john!.card = CreditCard(number: 1234_5678_9012_3456, customer: john!) 復制代碼在你關聯兩個實例后,它們的引用關系如下圖所示:
Customer 實例持有對 CreditCard 實例的強引用,而 CreditCard 實例持有對 Customer 實例的無主引用。
由于 customer 的無主引用,當你斷開 john 變量持有的強引用時,再也沒有指向 Customer 實例的強引用了:
由于再也沒有指向 Customer 實例的強引用,該實例被銷毀了。其后,再也沒有指向 CreditCard 實例的強引用,該實例也隨之被銷毀了: john = nil // 打印 “John Appleseed is being deinitialized” // 打印 ”Card #1234567890123456 is being deinitialized” 復制代碼最后的代碼展示了在john變量被設為nil后Customer實例和CreditCard實例的構造函數都打印出了“銷毀”的信息。
注意 上面的例子展示了如何使用安全的無主引用。對于需要禁用運行時的安全檢查的情況(例如,出于性能方面的原因),Swift還提供了不安全的無主引用。與所有不安全的操作一樣,你需要負責檢查代碼以確保其安全性。 你可以通過unowned(unsafe)來聲明不安全無主引用。如果你試圖在實例被銷毀后,訪問該實例的不安全無主引用,你的程序會嘗試訪問該實例之前所在的內存地址,這是一個不安全的操作。
引自:http://www.piggybear.net/?p=681
轉載于:https://juejin.im/post/5a312b0c518825619a02af43
總結
以上是生活随笔為你收集整理的Swift中的循环强引用 【使用无主引用解决】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Employee Bonus --lee
- 下一篇: 451 Sort Characters