簡體   English   中英

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

[英]Swift: Self.init called multiple times in initializer

這個讓我難過。 我無法弄清楚為什么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)
    }
}

除非我遺漏了某些內容,否則很明顯它只會調用init一次。 有趣的是,如果我注釋掉第二行,Swift抱怨所有路徑都沒有調用Super.init,哈哈。

我錯過了什么?

更新:

好的,所以問題肯定是在調用super.init時嘗試傳遞self 哈,我完全忘了我在做那件事。 我想我已經通過實驗編寫並編譯並認為它可能實際工作,但看起來它實際上是一個錯誤 ,它根本就是這樣編譯的。

無論如何,因為將self傳遞給初始化器是一種多余的,因為它是同一個對象,我將父初始化器更改為接受一個可選的文檔參數(它只是一個內部初始化器,所以沒什么大不了的),如果它nil我只是將它設置為self在父初始化程序中。

對於那些好奇的人來說,這就是父初始化程序(現在)的樣子:

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

我懷疑這是一個錯誤的診斷(即錯誤的錯誤消息)。 如果你有一個我們可以試驗的完整例子會非常有用,但是這條線沒有意義(我懷疑是潛在的問題):

    super.init(document: self, gravlNode: node)

你不能把self傳遞給super.init 你還沒有初始化(直到你調用super.init才初始化)。 例如,請考慮以下簡化代碼:

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

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

這會導致error: 'self' used before super.init call ,我認為這是正確的錯誤。

編輯:我相信Hamish肯定發現了編譯器錯誤。 您可以在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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM