使用NSUndoManager从异步撤消注册重做操作 [英] Registering a redo operation from an async undo with NSUndoManager
问题描述
使用UndoManager.registerUndo(withTarget:selector:object :)我可以注册一个撤消操作,并且在提供的选择器中调用此相同方法再次导致重做操作的注册.除非在选择器中我调用一个异步函数,然后需要注册重做操作,如下所示,否则此方法工作正常:
With UndoManager.registerUndo(withTarget:selector:object:) I can register an undo operation, and in the provided selector calling this same method again causes the registration of a redo operation. This works fine unless in the selector I'm calling an async function which then needs to register the redo operation, like this:
func job() {
doSomething()
registerUndo(self, undo)
}
func undo() {
async {
doSomethingElse()
registerUndo(self, job)
}
}
在这种情况下,两个对registerUndo()的调用实际上都注册了一个撤消操作,而不是我所期望的撤消然后是重做.有解决这个问题的方法吗?
In this case, both calls to registerUndo() actually register an undo operation, and not an undo and then a redo as I would expect. Is there a solution to this problem?
推荐答案
我发现具有一致的do/undo/redo机制的更好解决方案是使用Action对象
The better solution I found to have a coherent do/undo/redo mechanism is to use an Action object
class Action {
var someContextInfo ( like added/removed elements and indexes )
var actionType ( like add/remove )
func execute()
// Returns the symmetric action ( for example `add` will be a `remove` )
var symmetric: Action
}
func doAction(action: Action) {
action.execute()
manager.registerUndo(withTarget: self) { target in
target.doAction(action.symetric)
}
}
使用此解决方案可以执行/撤消/重做异步操作,因为您可以保留上下文并跟踪操作(完成,失败,进行中.).
Using this solution makes possible to do/undo/redo asynchronous operations, since you keep the context and keep track of actions ( finished, failed, in progress.. ).
但是正如评论中所说,这是一种罕见的情况.
But as said in the comments, it is an uncommon situation.
这篇关于使用NSUndoManager从异步撤消注册重做操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!