带有核心数据的NSUndoManager - 重做不起作用

时间:2010-03-10 18:10:58

标签: core-data undo-redo redo nsundomanager

我有一个基于Core Data文档的应用程序,它通过与NSManagedObjectContext关联的内置NSUndoManager支持撤消/重做。我设置了一些在Core Data中执行大量任务的操作,通过beginUndoGrouping / endUndoGrouping将所有这些任务包装到撤消组中,并由NSUndoManager处理。

撤消工作正常。我可以执行几个连续的操作,然后逐个撤消它们中的每一个,并且我的应用程序的状态得到正确维护。但是,永远不会启用“重做”菜单项。这意味着NSUndoManager告诉菜单没有要重做的项目。

我想知道为什么NSUndoManager在撤消后似乎忘记了项目,并且不允许重做?

我应该提到的一件事是我在打开/创建文档后禁用撤消注册。当我执行操作时,我致电enableUndoRegistrationbeginUndoGrouping,执行操作,然后致电processPendingChangessetActionName:endUndoGrouping,最后致电{{1} }。这可以确保只有特定的操作是可撤消的,并且我在这些操作之外进行的任何其他数据更改都不会被注意到NSUndoManager。这可能是问题的一部分,但如果是这样,我想知道为什么它会影响重做?

提前致谢。

3 个答案:

答案 0 :(得分:3)

实际上,只要你在-undo和-re​​do(以及之后的disableUndoRegistration)之前调用enableUndoRegistration,就可以实现你所追求的目标。

我相信您只是在对托管对象进行更改之前和之后调用启用(/禁用)UndoRegistration。这意味着您的“撤消”未在撤消管理器中注册,因此您无法“重做”它。

答案 1 :(得分:1)

我已通过以下方式解决了这个问题:

始终启用撤消注册,但我明确不想录制撤消的时间除外。

我已经了解到:

如果在执行要记录的更改之前启用撤消注册,并在提交这些更改后立即禁用,则NSUndoManager的重做堆栈永远不会被填充。

所以,永远不要打电话给disableUndoRegistration

答案 2 :(得分:1)

我在启用“重做”的同时调用了disableUndoManager。为此,我将NSUndoManager子类化并包含此方法:

-(void) undo
{
  [[appDelegate managedObjectContext] processPendingChanges];
  [self enableUndoRegistration];
  [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
  [super undo];
  [[appDelegate managedObjectContext] processPendingChanges];
  [self disableUndoRegistration];
}

如Stefanf在NSUndoManager, Core Data and selective undo/redo中所述:“NSUndoManager等待下一个运行循环周期,直到它注册您的更改”