您不需要检查委托初始化程序是否成功。如果委托初始化程序失败,则整个初始化过程将失败。
这在以下代码中很明显:
class EvenNumber {
var num: Int
var stringValue: String
init?(n: Int) {
guard n % 2 == 0 else { return nil }
self.num = n
stringValue = ""
}
convenience init?(str: String) {
guard let n = Int(str) else { return nil }
self.init(n: n)
print("hello")
stringValue = ""
}
}
EvenNumber(str: "5")
"
"hello"不会被打印出来,这意味着如果init(n:)
失败,则init(str:)
的其余部分不会被执行。
这里有一些支持文档(您需要向下滚动一点,在“初始化失败传播”下面):
无论哪种情况,如果您委托给另一个导致初始化失败的初始化器,则整个初始化过程立即失败,并且不会执行进一步的初始化代码。
"
(为了完整起见,包括此部分。)
现在你(或者将来看到这个问题的人)可能会问:“但是如果我希望在委托初始化程序
失败时执行其他操作怎么办?” 在这种情况下,您必须检查导致初始化程序失败的条件:
if n % 2 == 1 {
self.init(n: n)
} else {
}
为什么这个代码看起来有点“笨拙”呢?那是因为,我们假设你可以这样写(警告:这只是一种虚构的语法):
if self.init(n: n) {
} else {
}
要进入“失败”分支,我们必须已经运行了
self.init(n:)
。在它失败之前,
self.init(n:)
可能已经初始化了一些
let
属性。请记住,
let
属性只能初始化一次。因此,现在执行了
self.init(n: n)
,但编译器不知道哪些
let
属性已经被初始化。看到问题了吗?编译器如何验证您在“失败”分支中每个属性都恰好初始化了一次?