Swift:init 中 super.init 和 self.attribute 的顺序

Posted

技术标签:

【中文标题】Swift:init 中 super.init 和 self.attribute 的顺序【英文标题】:Swift: Order of super.init and self.attribute in init 【发布时间】:2014-08-16 01:34:48 【问题描述】:

我正在尝试像下面这样初始化一个子类:

class NameShape
    var numberOfSide: Int = 0
    var name:String
    func simpleDescription() -> String 
        return "A square with \(numberOfSide) sides."
    
    init (name: String)
        self.name = name
        


class Square:NameShape
    var sideLength: Double
    init(name: String, sideLength: Double)
        super.init(name: name)
        self.sideLength = sideLength
        numberOfSide = 4
    

    func area() ->Double 
        return sideLength * sideLength
    

    override func simpleDescription() -> String 
        return "A square with sides of length \(sideLength)."
    


报错property 'self.sideLength' not initialized at super.init call,于是切换self.sideLength = sideLengthsuper.init(name: name),如:

class Square:NameShape
    var sideLength: Double
    init(name: String, sideLength: Double)            
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSide = 4
    

    func area() ->Double 
        return sideLength * sideLength
    

    override func simpleDescription() -> String 
        return "A square with sides of length \(sideLength)."
    


现在很好,有人可以解释背后的原理吗? 谢谢!!!

【问题讨论】:

这似乎是一个非常奇怪的设计决定。从逻辑上讲,在对子类执行任何操作之前初始化基类是有意义的,包括设置属性。这当然是我使用过的所有其他语言的做法,包括 Objective C。 【参考方案1】:

之所以修改它,是因为 Apple 对这种语言的“安全”方法。在方法调用之前未初始化的任何未包装和未初始化的变量都会引发编译器错误。这是 Swift 中的一项安全功能。基本上,编译器试图让你免于做这样的事情:

init(name: String, sideLength: Double)            
    super.init(name: name)
    someFunctionThatUsesSideLengthBeforeItsInitialized(sideLength)
    self.sideLength = sideLength
    numberOfSide = 4

此方法someFunctionThatUsesSideLengthBeforeItsInitialized 可能会导致异常。在我看来,像super.init 这样的超类函数应该不受这条规则的约束。

【讨论】:

以上是关于Swift:init 中 super.init 和 self.attribute 的顺序的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能在 Swift 中调用 UIViewController 上的默认 super.init()?

swift 属性未在 super.init 调用中初始化

Swift:在从初始化程序返回之前,不会在所有路径上调用“super.init”?

swift 元类构造方法

swift 元类构造方法

当 init() 还初始化成员变量并引用“self”时,将 super.init() 放在哪里