3 回答

TA貢獻1887條經驗 獲得超5個贊
當兩個類相互指向并且您需要避免強引用循環時,使用隱式展開的可選變量(用!聲明)的真正好處與類初始化有關。例如:
A級<-> B級
A類的初始化例程需要創建(并擁有)B類,而B需要對A的弱引用:
class A {
let instanceOfB: B!
init() {
self.instanceOfB = B(instanceOfA: self)
}
}
class B {
unowned let instanceOfA: A
init(instanceOfA: A) {
self.instanceOfA = instanceOfA
}
}
現在,
B類需要引用要初始化的A類。
A類只有self在完全初始化后才能傳遞給B類的初始化器。
為了使A類在創建B類之前被視為已初始化,instanceOfB因此該屬性必須是可選的。
但是,一旦創建了A,就不得不使用instanceOfB訪問instanceOfB會很煩人!因為我們知道必須有一個B
為了避免這種情況,instanceOfB被聲明為一個隱式未包裝的可選(instanceOfB?。覀兛梢詢H使用instanceOfB對其進行訪問。(此外,我懷疑編譯器也可以不同地優化訪問)。
這本書的第464至466頁給出了一個示例。
摘要:
采用 ?如果該值將來可能變為nil,以便對此進行測試。
采用 !如果將來它真的不應該變為零,但是最初需要為零。

TA貢獻1796條經驗 獲得超4個贊
您應該超越語法糖。
有兩種完全不同的多態類型。語法糖僅使用這些類型中的一種或另一種。
當你Foo?以類型寫作時,你確實擁有Optional<Foo>,而當你寫作時,Foo!你確實具有ImplicitlyUnwrappedOptional<Foo>。
這是兩種不同的類型,它們也有所不同Foo。

TA貢獻1772條經驗 獲得超8個贊
?(可選)表示您的變量在
!時可能包含nil值。(解包器)表示在運行時使用變量(嘗試從中獲取值)時,變量必須具有內存(或值)。
主要區別在于,當可選值為nil時,可選鏈接會正常失敗,而當可選值為nil時,強制展開會觸發運行時錯誤。
為了反映可以在nil值上調用可選鏈接的事實,即使要查詢的屬性,方法或下標返回非可選值,可選鏈接調用的結果也始終是可選值。您可以使用此可選返回值來檢查可選鏈接調用是否成功(返回的可選包含一個值),或者由于鏈中的值為nil而失敗(返回的可選值為nil)。
具體來說,可選鏈接調用的結果與預期返回值的類型相同,但包裝在可選中。通常返回Int的屬性將返回Int?通過可選鏈訪問時。
var defaultNil : String? // declared variable with default nil value
println(defaultNil) >> nil
var canBeNil : String? = "test"
println(canBeNil) >> optional(test)
canBeNil = nil
println(canBeNil) >> nil
println(canBeNil!) >> // Here nil optional variable is being unwrapped using ! mark (symbol), that will show runtime error. Because a nil optional is being tried to get value using unwrapper
var canNotBeNil : String! = "test"
print(canNotBeNil) >> "test"
var cantBeNil : String = "test"
cantBeNil = nil // can't do this as it's not optional and show a compile time error
- 3 回答
- 0 關注
- 484 瀏覽
添加回答
舉報