什么';在swift中调用超级指定初始值设定项之前初始化属性值的目的是什么?

什么';在swift中调用超级指定初始值设定项之前初始化属性值的目的是什么?,swift,Swift,这是我的密码: 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!!!

这是我的密码:

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
和超类的初始化顺序是否真正重要。

来自文档:

安全检查1
指定的初始值设定项必须确保 由其类引入的属性在其委托之前初始化 直到超类初始值设定项

如上所述,仅充分考虑对象的内存 一旦其所有存储属性的初始状态为 知道。为了满足本规则,指定 初始值设定项必须确保其自身的所有属性都已初始化 在它放开链条之前

资料来源:

只需在
init

override init()
{
    y = 123
    super.init()  
}
你的论点

我认为这应该是:

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 在super.init之前 输入Base.init 调用了Test.setup y=123 离开Base.init 在super.init之后 如您所见,可以访问子类的
y
属性 在
super.init()
调用期间,即使 超类


比较Objective-C中的情况可能会很有趣 其中,始终首先调用
self=[super initXXX]
。这有 在init/dealloc方法中,属性访问self.prop的结果 是不安全的,直接访问实例变量
\u prop
是不安全的 建议使用,因为对象可能处于“部分构造状态”。 例如,见

所以这是Swift已经解决的问题之一
(以更严格的要求为代价)。

我认为Objective-C和Swift中部分构建的状态之间的“不安全”程度有所不同。在Objective-C(Apple runtime)中,每个实例变量都会自动初始化为已知值,即该类型的零值,该值适用于所有类型。因此,访问部分构造的状态至少仍有很好的定义,尽管它可能会打破程序员的假设。但在Swift中,并非所有类型都有“零值”(特别是非可选对象引用),因此访问部分构造的状态可能会导致不可能的情况。感谢您的回答,这让我非常困惑。