無主引用(unowned)
宣告屬性或者變數時,在前面加上unowned關鍵字表示這是一個無主引用,無主引用不能設定為nil,因為非可選型別的變數不允許被賦值為nil。
兩個屬性,其中一個為可選型別,另外一個不是可選型別,而且相互引用,這種情況下一般使用無主引用去解決迴圈強引用。
案例
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") }
}
複製程式碼
注意
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