这是我的代码:
class Base
{
init(){
print("Super!")
}
}
class Test : Base
{
internal var y:Int
convenience init(_ a:Int)
{
self.init()
print("\(a)")
}
override init()
{
super.init() //Error!!! Property 'self.y' not initialized at super.init call
y = 123
}
}
我认为应该编译:
y
在课程' Base'中是不可见的,y
和超级课程的初始化顺序是否真的没有物质
答案 0 :(得分:5)
你的论点
我认为应该编译:
y在类' Base'中是不可见的,是否是初始化的顺序 我和超级课程并不重要。
不正确,不是安全的。
超类init
可以调用实例
在子类中重写的方法。那是(至少一个)
之所以必须在调用 super.init()
之前初始化所有子类属性的原因。
一个简单的例子:
class Base
{
init(){
print("enter Base.init")
setup()
print("leave Base.init")
}
func setup() {
print("Base.setup called")
}
}
class Test : Base
{
internal var y:Int
override init()
{
y = 123
print("before super.init")
super.init()
print("after super.init")
}
override func setup() {
print("Test.setup called")
print("y = \(y)")
}
}
输出:
before super.init enter Base.init Test.setup called y = 123 leave Base.init after super.init
如您所见,访问子类的y
属性
在super.init()
通话期间,即使不知道
超类。
比较Objective-C中的情况可能会很有趣
始终首先调用self = [super initXXX]
。这有
结果是init / dealloc方法中的属性访问self.prop
是不安全的,直接访问实例变量_prop
建议因为对象可能处于部分构造状态"。
请参阅示例Should I refer to self.property in the init method with ARC?。
所以这是Swift已经解决的问题之一 (以更严格的要求为代价)。
答案 1 :(得分:3)
来自文档:
安全检查1
指定的初始化程序必须确保所有的 其类引入的属性在委托之前初始化 一个超类初始化器。如上所述,只考虑对象的内存 一旦所有存储属性的初始状态为,就初始化 众所周知。为了满足这条规则,指定 初始化程序必须确保初始化所有自己的属性 在把它放到链子之前。
来源:Swift Language Guide: Initialization
只需在init
override init()
{
y = 123
super.init()
}