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
isExecutingkey path whenever the execution state of your operation object changes.
In your custom implementation,you must generate KVO notifications for the
isFinishedkey 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")
}
}