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ügeActionData
eben 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)
: