2010-03-10 55 views
1

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

撤消工作正常。我可以执行几个连续的操作,然后每个操作都依次撤消,并且我的应用程序的状态保持正确。但是,“重做”菜单项从未启用。这意味着NSUndoManager正在告诉菜单没有要重做的项目。

我想知道为什么NSUndoManager似乎忘记了项目,一旦他们被撤消,并且不允许redo发生?

我应该提及的一件事是,在打开/创建文档后,我禁用撤销注册。当我执行某个操作时,我打电话给enableUndoRegistration,beginUndoGrouping,执行操作,然后拨打processPendingChanges,setActionName:,endUndoGrouping,最后是disableUndoRegistration。这可以确保只有特定的操作才能被撤消,并且除此之外的任何其他数据更改都不会被注意到NSUndoManager。这可能是问题的一部分,但如果是这样,我想知道为什么它会影响重做?

在此先感谢。

回答

1

我已经修复了这个问题:

饲养撤销注册时启用所有的时间,除了当我明确不想记录索马里发展事务处的时间。

我了解到:

如果启用刚刚执行要记录更改之前撤销登记,并提交这些更改后立即禁用,则NSUndoManager的重做堆栈永远不会被填充。因此,不要致电disableUndoRegistration

3

实际上,只要你在-undo和-re​​do(和disableUndoRegistration之后)之前调用enableUndoRegistration,你就可以实现你以前的样子。

我相信你只是在更改管理对象之前和之后调用enable(/ disable)UndoRegistration。这意味着你的'撤销'没有注册到撤销管理器,因此你不能'重做'它。

1

我在启用“重做”的情况下调用了disableUndoManager。要做到这一点,我子类NSUndoManager,其中包括此方法:

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

正如NSUndoManager, Core Data and selective undo/redo由Stefanf说:“NSUndoManager等待下一次运行循环周期,直到它注册更改”