Swift:Self.init在初始化程序中多次调用

dev*_*os1 5 initializer swift swift3

这个让我难过.我无法弄清楚为什么Swift抱怨self.init在这段代码中不止一次被调用:

public init(body: String) {
    let parser = Gravl.Parser()

    if let node = parser.parse(body) {
        super.init(document: self, gravlNode: node)
    } else {
        // Swift complains with the mentioned error on this line (it doesn't matter what "whatever" is):
        super.init(document: self, gravlNode: whatever)
    }
}
Run Code Online (Sandbox Code Playgroud)

除非我遗漏了某些东西,否则它只会召唤init一次.有趣的是,如果我评论第二行,Swift抱怨所有路径都没有调用Super.init,哈哈.

我错过了什么?

更新:

好的,所以问题肯定是试图传递self给super.init的调用.哈,我完全忘了我在做那件事.我想我已经通过实验编写并编译并认为它可能实际工作,但看起来它实际上是一个错误,它根本就是这样编译的.

无论如何,因为传递self给初始化器是多余的,因为它是同一个对象,我改变了父初始化器接受一个可选的文档参数(它只是一个内部初始化器,所以没什么大不了的),如果是,nil我只是将它设置self为父级初始化.

对于那些好奇的人来说,这就是父初始化程序(现在)的样子:

internal init(document: Document?, gravlNode: Gravl.Node) {
    self.value = gravlNode.value
    super.init()
    self.document = document ?? self as! Document
    // other stuff...
}
Run Code Online (Sandbox Code Playgroud)

Rob*_*ier 3

我怀疑这是一个错误的诊断(即错误的错误消息)。如果您有一个我们可以试验的完整示例,那将非常有帮助,但是这一行没有意义(我怀疑这是根本问题):

    super.init(document: self, gravlNode: node)
Run Code Online (Sandbox Code Playgroud)

你不能传递selfsuper.init. 您尚未初始化(在调用 之前,您尚未初始化super.init)。例如,考虑以下简化代码:

class S {
    init(document: AnyObject) {}
}

class C: S {
    public init() {
        super.init(document: self)
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这导致了error: 'self' used before super.init call正确的错误。

编辑:我相信哈米什肯定发现了编译器错误。您可以在 Xcode 8.3.1 中以这种方式利用它(尚未在 8.3.2 上测试):

class S {
    var x: Int
    init(document: S) {
        self.x = document.x
    }
}

class C: S {
    public init() {
        super.init(document: self)
    }
}

let c = C() // malloc: *** error for object 0x600000031244: Invalid pointer dequeued from free list
Run Code Online (Sandbox Code Playgroud)