这是我的代码:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我认为应该编译:
y在'Base'类中是不可见的,无论是y's'和超类的初始化顺序是否真的无关紧要.
你的论点
我认为应该编译:
y在类'Base'中是不可见的,y和超类的初始化顺序是否真的无关紧要.
是不正确的,这将不会是安全的.
超类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)")
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
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]总是首先调用的情况可能会很有趣.这导致self.propinit/dealloc方法中的属性访问是不安全的,并且建议直接访问实例变量_prop,因为该对象可能处于"部分构造状态".例如,请参阅使用ARC在init方法中引用self.property吗?.
所以这是Swift已经解决的问题之一(以更严格的要求为代价).