[英]Swift class with no initializers but with property observer
我剛剛開始學習敏捷,對類初始化器有疑問。 這是我的示例代碼:
struct Resolution {
var width = 0
var height = 0
}
let someResolution = Resolution()
class TV {
var res: Resolution! {
didSet {
res.width = 1
res.height = 1
}
}
}
var television = TV()
var resolution = Resolution()
television.res = resolution
我正在嘗試使用屬性觀察器。 當我隱式打開結構的屬性觀察器類型時,一切正常。 否則,它說“類沒有初始化程序。我很困惑為什么我應該隱式解開結構。在此先感謝!
您的問題尚不完全清楚,但是我想您是在問為什么不能替換這個問題:
var res: Resolution! {
…有了這個:
var res: Resolution {
您的線索來自完整的編譯器錯誤消息,您可以通過查看編譯器日志(如果您在操場上,則可以在操場上控制台)中查看:
error: class 'TV' has no initializers
class TV {
^
note: stored property 'res' without initial value prevents synthesized initializers
var res: Resolution {
^
error: 'TV' cannot be constructed because it has no accessible initializers
var television = TV()
當屬性的類型為Resolution!
,您是說:“它可能為零,但是如果有人嘗試在它為零時讀取它,那將是一場可怕的災難,我的整個應用程序都將崩潰。”因此,Swift將TV
的res
設置為nil進行初始化,並希望您能夠立即將其設置為其他內容。
但是,當屬性的類型為Resolution
,您說的是:“即使從沒有人看,它也永遠不會為零,永遠不會,甚至永遠不會。”這意味着從實例化TV
, res
必須具有一個值。 但是那個值應該是多少? 沒有默認設置。 如果類型為Resolution
則有兩個選擇:
使用屬性初始值設定項將其設置為一些默認值(這就是您要嘗試執行的操作):
class TV { var res: Resolution = Resolution(width: 1, height: 1) }
…或使用初始化程序,您可以讓Swift推斷類型:
class TV { var res = Resolution(width: 1, height: 1) }
在實例化該類時,請問創建TV
人指定初始值:
class TV { init(res: Resolution) { self.res = res } var res: Resolution { didSet { res.width = 1 res.height = 1 } } } var resolution = Resolution() var television = TV(res: resolution)
除了:所有這些絕對沒有意義 ,因為在設置分辨率后,您立即將width&height更改為1(是什么?!),但是它確實可以編譯。
這樣,來自編譯器的“合成的初始化器”消息就會出現? Swift會自動為您的類創建一個空的init()
,它不會執行任何操作,但是如果有任何非可選屬性要初始化,則不會執行任何操作。 如果有,則必須編寫自己的初始化程序。
(請注意,如果TV
是結構,則Swift 會為您生成該init(res:)
。它與結構有關,但與類無關。)
第三種選擇是使類型為Resolution?
:
class TV {
var res: Resolution? {
didSet {
res?.width = 1
res?.height = 1
}
}
}
這是比Resolution!
更好的選擇Resolution!
,這只是一場等待發生的崩潰。 隱式解開的可選對象只能是不得已而為之,這是在非常具體,經過仔細考慮的情況下使用的。
在初始化時間結束之前,每個實例變量都必須具有一個值。
如果您不使用Optional,那么您必須在此處提供一個實際的Resolution實例作為res
的值,而您並沒有這樣做。
如果確實使用Optional,則編譯器會提供nil
作為值,因此可以滿足對值的需要。
一種可能是這樣編寫您的類:
電視類{var res = Resolution(){didSet {res.width = 1 res.height = 1}}}
現在res
具有一個初始值:即一個實際的Resolution實例。
但是你在做什么並沒有錯 。 當您知道無法在初始化時為實例變量提供值,但是打算在此后不久提供一個值時,通常使用Optional即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.