Core data NSEndomanager具有核心数据-重做不工作

Core data NSEndomanager具有核心数据-重做不工作,core-data,undo-redo,redo,nsundomanager,Core Data,Undo Redo,Redo,Nsundomanager,我有一个基于核心数据文档的应用程序,它通过与NSManagedObjectContext关联的内置NSEndomanager支持撤消/重做。我设置了一些操作,它们在核心数据中执行大量任务,通过beginUndoGrouping/endUndoGrouping将所有这些任务包装到一个撤销组中,并由NSUndoManager处理 撤销很好。我可以执行几个连续的操作,然后依次撤消其中的每个操作,我的应用程序的状态将得到正确维护。但是,“重做”菜单项从未启用。这意味着NSUndoManager正在告诉菜

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

撤销很好。我可以执行几个连续的操作,然后依次撤消其中的每个操作,我的应用程序的状态将得到正确维护。但是,“重做”菜单项从未启用。这意味着NSUndoManager正在告诉菜单没有要重做的项

我想知道为什么NSUndoManager似乎忘记了撤销的项目,而不允许重做

我应该提到的一点是,在打开/创建文档后,我将禁用撤消注册。执行操作时,我调用enableUndoRegistration、beginUndoGrouping、执行操作,然后调用processPendingChanges、setActionName:、endUndoGrouping,最后是disableUndoRegistration。这样可以确保只有特定的操作是可撤消的,而我在这些操作之外所做的任何其他数据更改都不会被NSUndoManager注意到。这可能是问题的一部分,但如果是这样,我想知道为什么它会影响重做


提前感谢。

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

保持撤消注册一直处于启用状态,除非我明确不想记录撤消

我了解到:

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


因此,永远不要调用disableUndoRegistration。

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

保持撤消注册一直处于启用状态,除非我明确不想记录撤消

我了解到:

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


因此,永远不要调用disableUndoRegistration。

事实上,只要在-undo和-redo之前调用enableUndoRegistration,在它们之后调用disableUndoRegistration,就可以实现您所追求的目标


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

实际上,只要在-undo和-redo之前调用enableUndoRegistration,在它们之后调用disableUndoRegistration,您就可以实现您的目标


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

我在启用重做的同时调用了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将等待下一个运行循环周期,直到它注册您的更改为止

我在启用重做的同时调用了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等待下一个运行循环周期,直到它注册您的更改