这是我的代码:
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
'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)") } }
输出:
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.prop
init/dealloc方法中的属性访问是不安全的,并且建议直接访问实例变量_prop
,因为该对象可能处于"部分构造状态".例如,请参阅使用ARC在init方法中引用self.property吗?.
所以这是Swift已经解决的问题之一(以更严格的要求为代价).