2017-05-30 38 views
0

我正在關注Ray Wenderlich的網站關於Swift中ARC的一個教程,我很想知道爲什麼在操場上創建一個類時,可選的允許但不是隱式的可選項?爲什麼在類的init方法中不需要隱式的可選項?

操場代碼我至今是:

class User { 
    var name: String 
    init(name: String) { 
     self.name = name 
     print("User \(name) is initialized") 
    } 
    deinit { 
     print("User \(name) is being deallocated") 
    } 
} 

class Phone { 
    let model: String 
    var owner: User? 
    init(model: String) { 
     self.model = model 
     print("Phone \(model) is initialized") 
    } 
    deinit { 
     print("Phone \(model) is being deallocated") 
    } 
} 

do { 
    let user1 = User(name: "John") 
} 
let user2 = User.init(name: "Berry") 

在手機類,如果我改變了所有者變量的隱式可選的感嘆號,然後在操場不但是如果拋出一個錯誤我刪除了問號或者不要讓它成爲可選的,然後我收到一個錯誤。

不隱式可選強制應用程序崩潰,如果它沒有設置?

任何幫助被理解爲深刻理解爲什麼隱式可選是好的。

回答

5

隱式可選仍然是可選的,因此它可以是nil,並且它不需要在初始化時設置。但是,如果您無條件地訪問,那麼您仍然會得到例外

如果您Phone類分別爲:

class Phone { 
    let model: String 
    var owner: User! 
    init(model: String) { 
     self.model = model 
     print("Phone \(model) is initialized") 
    } 
    deinit { 
     print("Phone \(model) is being deallocated") 
    } 
} 

你說

var aPhone = Phone(model:"iPhone7") 
let ownerName = aPhone.owner.name 

,那麼你會得到一個異常的第二行,因爲隱含展開可選的是nil。如果owner的類型爲User?,則該行相當於編寫let ownerName = aPhone.owner!.name

在初始化時不能分配值的情況下,隱式解包選項非常有用,但此後不久將分配一個值,因爲它避免了需要連續打開變量。

例如,隱式解包選項通常用於視圖控制器中的@IBOutlet屬性。屬性將由故事板加載過程設置,但是在視圖控制器對象被初始化之後。由於您知道在您的代碼運行時該屬性將具有值,因此使用隱式解包的可選屬性是安全的,並且可以避免不斷打開屬性。

您的樣本Phone類不是一個很好的隱式解包選項;無論是簡單的可選(如您所示)還是所需的初始化參數都是合適的,具體取決於電話是否可以取消。

+1

在你的例子'let owner = aPhone.owner'不應該導致一個異常。它應該導致所有者擁有'String?'類型和一個零值。解引用所有者將導致異常。將最後一行更改爲'let owner = aPhone.owner.name'將導致異常。 –

+2

謝謝。修正了。 – Paulw11

相關問題