![](/img/trans.png)
[英]iOS Swift convenience initializer self used before self.init called
[英]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.