Verwenden von nicht besessenem Inhalt einer Erfassungsliste, die einen Absturz verursacht, auch wenn der Block selbst nicht ausgeführt wird

Hier habe ich mit Lecks gespielt, also habe ich absichtlich einen starken Referenzzyklus durchgeführt, um festzustellen, ob die Instrumente etwas erkennen, und ich habe unerwartete Ergebnisse erhalten. Das in Instruments gezeigte Leck ist sicherlich sinnvoll, aber das Random Crash ist ein bisschen mysteriös (aufgrund zweier Tatsachen, die ich später erwähnen werde).

as ich hier habe, ist eine Klasse namensSomeClass:

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")}
}

Auch ich habe zwei Szenen, dieGameScene:

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(){}
} 

Und schließlich dieMenuScene das ist identisch mit demGameScene, nur mit einem leerendidMoveToView Methode (es hat nurtouchesBegan Methode implementiert).

Reproducing the Crash

Der Absturz kann reproduziert werden, indem einige Male zwischen den Szenen gewechselt wird. Auf diese Weise wird das Leck passieren, weilsomeInstance wird vom @ beibehaltclosure Variable und dasclosure -Variable wird vom @ beibehaltsomeInstance Variable, also haben wir einen Zyklus. Dies führt jedoch nicht zum Absturz (es tritt nur ein Leck auf). Wenn ich tatsächlich versuche, @ hinzuzufügself.method() innerhalb eines Closures stürzt die App ab und ich bekomme folgendes:

und das

Das gleiche Absturz kann ich erzeugen, wenn ich versuche, auf ein @ zuzugreifunowned reference, wenn das Objekt, auf das es verweist, freigegeben wird, z. Wenn der Abschluss die erfasste Instanz überlebt. Das macht Sinn, ist aber hier nicht der Fall (Schließung wird nie ausgeführt).

er mysteriöse Te

er mysteriöse Teil ist, dass dieser Absturz passiertnur für iOS 9.1 undnicht unter iOS9.3. Und ein weiteres Rätsel ist, dass die App abstürztnach dem Zufallsprinzi, aber meistens innerhalb der ersten zehn Übergänge. Der seltsame Teil ist auch der Grund, warum es abstürzt, wenn der Abschluss nie ausgeführt wird oder auf die erfasste Instanz nicht zugegriffen wird (zumindest nicht von mir).

Lösung zum Problem, aber nicht die Antwort auf die Frage

atürlich kann der Absturz durch Unterbrechen des Zyklus auf verschiedene Arten behoben werden, und mir ist bewusst, dass ich @ verwenden solltunowned nur, wenn ich völlig sicher bin, dass die erfasste Instanz nach der Initialisierung niemals null wird. Aufgrund der Tatsache, dass ich diesen Abschluss überhaupt nicht ausgeführt habe, nachdem er die Szene überlebt hat, ist dieser Absturz für mich jedoch ziemlich umständlich. Erwähnenswert ist auch, dass Szenen nach jedem Übergang erfolgreich deinitiert werden.

Interessan

Wenn ich @ benutweak self innerhalb einer Capture-Liste stürzt die App nicht ab (das Leck ist natürlich noch vorhanden). Was Sinn macht, denn wenn die Szene @ winil bevor der Block freigegeben wird, verhindert der Zugriff auf die Szene durch optionale Verkettung einen Absturz. Aber der interessante Teil ist, dass selbst wenn ich @ benutforced unwrapping so wird es nicht abstürzen:

let closure = {[weak self] in
      someInstance.method() 
      self!.method()  
}

Was mich zum Nachdenken bringt ... Schätzen Sie Hinweise zum Debuggen oder Erklärungen zu den Ursachen des Absturzes ...

BEARBEITEN

ier ist der Gith repo

Antworten auf die Frage(4)

Ihre Antwort auf die Frage