Использование неизвестных внутри списка захвата, вызывающего сбой, даже сам блок не выполняется

Здесь я играл с утечками, поэтому я специально сделал сильный референсный цикл, чтобы увидеть, обнаружат ли инструменты что-то, и я получил неожиданные результаты. Утечка, показанная в приборах, безусловно, имеет смысл, нослучайный сбой немного загадочно (из-за двух фактов я упомяну позже).

У меня здесь есть класс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Сделки рЕПО

Ответы на вопрос(2)

Ваш ответ на вопрос