無主引用以及隱式解析可選屬性
兩個屬性都必須有值,並且初始化完成後永遠不會為nil。在這種場景中,需要一個類使用無主屬性,而另外一個類使用隱式解析可選屬性。
隱式解析可選型別
這種型別的可選狀態被定義為隱式解析可選型別(implicitly unwrapped optionals)。把想要用作可選的型別的後面的問號(String?
)改成感嘆號(String!
)來宣告一個隱式解析可選型別。
注意: 如果你在隱式解析可選型別沒有值的時候嘗試取值,會觸發執行時錯誤。和你在沒有值的普通可選型別後面加一個驚歎號一樣。
案例
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
}
}
複製程式碼
通過在型別結尾處加上感嘆號(City!
)的方式,將Country
的capitalCity
屬性宣告為隱式解析可選型別的屬性。這意味著像其他可選型別一樣,capitalCity
屬性的預設值為nil
,但是不需要展開它的值就能訪問它。
由於capitalCity
預設值為nil
,一旦Country
的例項在建構函式中給name
屬性賦值後,整個初始化過程就完成了。這意味著一旦name
屬性被賦值後,Country
的建構函式就能引用並傳遞隱式的self
。Country
的建構函式在賦值capitalCity
時,就能將self
作為引數傳遞給City
的建構函式。
以上的意義在於你可以通過一條語句同時建立Country
和City
的例項,而不產生迴圈強引用,並且capitalCity
的屬效能被直接訪問,而不需要通過感嘆號來展開它的可選值:
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”
複製程式碼
在上面的例子中,使用隱式解析可選值意味著滿足了類的建構函式的兩個構造階段的要求。capitalCity
屬性在初始化完成後,能像非可選值一樣使用和存取,同時還避免了迴圈強引用。
引自:http://www.piggybear.net/?p=687