runAction auf SKNode wird nicht abgeschlossen

Ich verwende eine Unterklasse NSOperation, um die serielle Ausführung von @ zu erhalteSKAction wie in dieser Frage beschrieben:Wie kann man NSOperation in Swift unterklassifizieren, um SKAction-Objekte für die serielle Ausführung in die Warteschlange zu stellen?

Ich habe dann die vorherige Unterklasse geändert, um Animationen für mehrere Knoten zu gruppieren:https: //stackoverflow.com/a/30600718/54078

At last, da ich nach @ Completion Block ausführen mussSKAction abgeschlossen, habe ich den Code leicht modifiziert, indem ich statt eines Arrays von Tupeln ein Array von struct verwendet habe.

struct ActionData {
    let node:SKNode
    let action:SKAction
    let completion: () -> ()

    init (node:SKNode, action:SKAction, completion:() -> () = {}) {
        self.node = node
        self.action = action
        self.completion = completion
    }
}

class ActionOperation : NSOperation
{

    let _theActions:[ActionData]

    var _finished = false // Our read-write mirror of the super's read-only finished property
    var _executing = false // Our read-write mirror of the super's read-only executing property

    var _numberOfOperationsFinished = 0 // The number of finished operations


    /// Override read-only superclass property as read-write.
    override var executing:Bool {
        get { return _executing }
        set {
            willChangeValueForKey("isExecuting")
            _executing = newValue
            didChangeValueForKey("isExecuting")
        }
    }

    /// Override read-only superclass property as read-write.
    override var finished:Bool {
        get { return _finished }
        set {
            willChangeValueForKey("isFinished")
            _finished = newValue
            didChangeValueForKey("isFinished")
        }
    }


    // Initialisation with one action for one node
    //
    // For backwards compatibility
    //
    init(node:SKNode, action:SKAction) {
        let donnees = ActionData(node: node, action: action, completion: {})
        _theActions = [donnees]

        super.init()
    }

    init (lesActions:[ActionData]) {
        _theActions = lesActions

        super.init()
    }

    func checkCompletion() {
        _numberOfOperationsFinished++

        logGeneral.debug(">> Block completed: \(self._numberOfOperationsFinished)/\(self._theActions.count) " + self.name!)

        if _numberOfOperationsFinished ==  _theActions.count {
            self.executing = false
            self.finished = true
            logGeneral.debug("Operation Completed: " + self.name!)
        }

    }

    override func start()
    {
        if cancelled {
            finished = true
            return
        }

        executing = true

        if name == nil {
            name = "unknown"
        }


        _numberOfOperationsFinished = 0
        var operation = NSBlockOperation()

        var compteur = 0
        for actionData in _theActions {
            compteur++

            var actionName = "???"
            if let name = actionData.node.name {
                actionName = name
            }

            logGeneral.debug("operation : \(compteur)/\(self._theActions.count) " + self.name! + " " + actionName)
            operation.addExecutionBlock({
                actionData.node.runAction(actionData.action,completion:{
                    actionData.completion()
                    self.checkCompletion() })
            })
        }

        logGeneral.debug("Execute: " + self.name!)
        NSOperationQueue.mainQueue().addOperation(operation)

    }
}

Die Hauptidee ist es, Animationen zu erstellen, indem Sie Daten von @ hinzufügeActionDataeben Sie @ ein, hängen Sie sie an ein Array an und übertragen Sie dieses Array an dasActionAnimation Objekt

In einigen zufälligen Fällen, einigerunAction wird nicht abgeschlossen: Sie werden gestartet, aber einige von ihnen werden nicht zufällig abgeschlossen. Hier ist ein typisches Protokoll, in dem 6 Blöcke gestartet, aber nur 5 abgeschlossen wurden:

start(): operation : 1/6 ???
start(): operation : 2/6 suppressionPion1
start(): operation : 3/6 suppressionPion2
start(): operation : 4/6 suppressionPion3
start(): operation : 5/6 suppressionPion4
start(): operation : 6/6 suppressionGroupe1
start(): Execute: animerSupprimer
checkCompletion(): >> Block completed: 1/6
checkCompletion(): >> Block completed: 2/6
checkCompletion(): >> Block completed: 3/6
checkCompletion(): >> Block completed: 4/6
checkCompletion(): >> Block completed: 5/6

n diesem Fall nur einrunAction konnte nicht abgeschlossen werden, in anderen Fällen 2, 3 oder keine.

Ich verstehe wirklich nicht, wo das Problem herkommt.

AKTUALISIERE

In einigen Fällen stürzte die App mit @ EXC_BAD_ACCESS auf Hauptthread. Dies scheint mit @ zu tun zu habeSKCSprite::update(double):

Antworten auf die Frage(0)

Ihre Antwort auf die Frage