在這裏,我在玩漏洞,所以我有意識地製作了一個強大的參考週期,以查看儀器是否會檢測到某些東西,而我意想不到的結果。儀器中顯示的泄漏當然有意義,但隨機崩潰有點神祕(由於我將在後面提到的兩個事實)。在捕獲列表中使用無主模塊導致崩潰,即使模塊本身沒有執行
我這裏有一個名爲SomeClass
類:
class SomeClass{
//As you can guess, I will use this shady property to make a strong cycle :)
var closure:(()->())?
init(){}
func method(){}
deinit {print("SomeClass deinited")}
}
我也有兩個場景中,GameScene
:
class GameScene: SKScene {
override func didMoveToView(view: SKView) {
backgroundColor = .blackColor()
let someInstance = SomeClass()
let closure = {[unowned self] in
someInstance.method() //This causes the strong reference cycle...
self.method()
}
someInstance.closure = closure
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let nextScene = MenuScene(fileNamed: "MenuScene"){
nextScene.scaleMode = .AspectFill
let transition = SKTransition.fadeWithDuration(1)
view?.presentScene(nextScene, transition: transition)
}
}
deinit {print("GameScene deinited")}
func method(){}
}
最後,MenuScene
這等同於GameScene
,只是用空的didMoveToView
方法(它只有touchesBegan
方法實現)。
再現崩潰
崩潰可以通過場景之間的轉換數次被重現。通過這樣做,泄漏將發生,因爲someInstance
由closure
變量保留,並且closure
變量由someInstance
變量保留,所以我們有一個循環。但是,這仍然不會產生崩潰(它只會泄漏)。當我真正嘗試添加self.method()
封閉,應用程序崩潰的內部,我得到這個:
這:
完全相同的崩潰,我可以,如果我產生嘗試訪問unowned
引用時,它引用的對象被釋放,例如。當關閉超過捕獲的實例。這是有道理的,但情況並非如此(關閉從未執行)。
神祕的部分
神祕的部分是這個崩潰發生僅在iOS 9.1和不是iOS9.3。另一個神祕的事實是,應用崩潰隨機,但大部分在前十個過渡。此外,怪異的部分是爲什麼它會崩潰,如果從不執行閉包,或者它捕獲的實例沒有被訪問(至少不是我)。
解決這個問題,但沒有答案的問題
當然墜毀可以在幾個方面打破循環來解決,而且我知道我應該使用unowned
只有當我完全確保捕獲的實例永遠不會在初始化後變爲零。但是,由於事實上我還沒有執行過這個關閉,所以在它失效之後,這次崩潰對我來說非常尷尬。另外,值得一提的是,在每次轉換之後,場景都能成功地進行定義。
有趣
如果我使用weak self
捕獲列表裏面,應用程序將不會崩潰(泄漏仍然存在,當然)。這是有道理的,因爲如果在解除分配塊之前場景變爲nil
,通過可選鏈接訪問場景將防止崩潰。但有趣的是,即使我用forced unwrapping
這樣的,它不會崩潰:
let closure = {[weak self] in
someInstance.method()
self!.method()
}
這讓我覺得...欣賞有關如何調試這或解釋什麼導致崩潰的任何提示.. 。
編輯:
這裏是Github上repo
如果它沒有在9.3崩潰,那麼它可能是一個錯誤。這是你的報告的方式? [SR-1006](https://bugs.swift.org/browse/SR-1006)看起來是同樣的問題。 – Sulthan
@Sulthan Nope,那不是我的錯誤報告......那麼,我開始了一個賞金,看看有人能夠真正證明這是一個錯誤,並解釋在這種情況下應該是什麼樣的預期行爲。就我個人而言,我認爲它應該泄漏,但不應該崩潰,但我們會看到... – Whirlwind
我很確定它不應該崩潰,如果你不實際執行該塊。 – Sulthan