什么';在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中,并非所有类型都有“零值”(特别是非可选对象引用),因此访问部分构造的状态可能会导致不可能的情况。感谢您的回答,这让我非常困惑。