Rob为子类化NSOperation提供了
a great Objective-C solution,以实现SKAction对象的串行排队机制.我在自己的Swift项目中成功实现了这一点.
import SpriteKit class Actionoperation : NSOperation { let _node: SKNode // The sprite node on which an action is to be performed let _action: SKAction // The action to perform on the sprite node 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 /// 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") } } /// Save off node and associated action for when it's time to run the action via start(). init(node: SKNode,action: SKAction) { // This is equiv to ObjC: // - (instancetype)initWithNode(SKNode *)node (SKAction *)action // See "Exposing Swift Interfaces in Objective-C" at https://developer.apple.com/library/mac/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html#//apple_ref/doc/uid/TP40014216-CH4-XID_35 _node = node _action = action super.init() } /// Add the node action to the main operation queue. override func start() { if cancelled { finished = true return } executing = true NSOperationQueue.mainQueue().addOperationWithBlock { self._node.runAction(self._action) { self.executing = false self.finished = true } } } }
要使用Actionoperation,请在客户端类中实例化NSOperationQueue类成员:
var operationQueue = NSOperationQueue()
在init方法中添加以下重要行:
operationQueue.maxConcurrentOperationCount = 1; // disallow follow actions from overlapping one another
然后当您准备好向其添加SKActions时,它们会连续运行:
operationQueue.addOperation(Actionoperation(node: mySKNode,action: mySKAction))
您是否需要在任何时候终止操作:
operationQueue.cancelAllOperations() // this renders the queue unusable; you will need to recreate it if needing to queue anymore actions
希望有所帮助!
根据
the document:
In your custom implementation,you must generate KVO notifications for the
isExecuting
key path whenever the execution state of your operation object changes.
In your custom implementation,you must generate KVO notifications for the
isFinished
key path whenever the finished state of your operation object changes.
所以我认为你必须:
override var executing:Bool { get { return _executing } set { willChangeValueForKey("isExecuting") _executing = newValue didChangeValueForKey("isExecuting") } } override var finished:Bool { get { return _finished } set { willChangeValueForKey("isFinished") _finished = newValue didChangeValueForKey("isFinished") } }