几个月来我一直在修补 Cocoa,并且正在尝试将撤消/重做支持添加到我正在编写的一个严格用于学习目的的 Cocoa 应用程序中,该应用程序允许您调整 iTunes 曲目元数据。多亏了 NSUndoManager 的prepareWithInvocationTarget:
方法,我已经具备了基础知识——例如,您可以撤消/重做对所选曲目的播放计数和上次播放日期的更改。(我正在使用 appscript-objc 来获取/设置 iTunes 曲目数据。)
但是,由于更新大量 iTunes 曲目可能需要一些时间,我想让用户能够在进行中取消撤消/重做操作,但我没有看到一个明显的机制来完成这个使用 NSUndoManager。我该怎么做呢?
编辑:
澄清一下,再考虑一下,我想我真正想要的是一种操作撤消/重做堆栈的方法,这样我就可以避免 Rob Napier 在他的回答中提到的“不一致状态”。
因此,为了响应未进行任何更改而失败的撤消操作(例如,在调用撤消之前,用户打开了阻止 Apple 事件的 iTunes 首选项窗口),撤消操作可以保留在撤消堆栈的顶部,并且重做堆栈将保持不变。如果操作在中途被取消或失败,那么我想将一个操作推送到重做堆栈上,该操作可以反转经过的更改(如果有的话),并在撤消堆栈顶部进行一个操作,该操作应用未完成的更改'成功。我想在撤消堆栈和重做堆栈之间有效地拆分操作可能会引起用户混淆,但这似乎是处理该问题的最宽容的方式。
我怀疑这个问题的答案可能是“编写你自己的该死的撤消管理器”,“你的撤消操作不应该失败”或“你不必要地过度复杂化”,但我很好奇。:)