Cocoa NSUndoManager、核心数据和选择性撤消/重做

Cocoa NSUndoManager、核心数据和选择性撤消/重做,cocoa,core-data,nsmanagedobject,nsmanagedobjectcontext,nsundomanager,Cocoa,Core Data,Nsmanagedobject,Nsmanagedobjectcontext,Nsundomanager,我正在开发一个核心数据应用程序,它有一个相当大的托管对象层次结构,类似于树 创建基础对象时,它会创建几个子对象,这些子对象又会创建自己的子对象,依此类推。每个子对象都可以使用NSURLConnections收集信息 现在,我想在managedObjectContext中使用undoManager支持undo/redo。问题是,如果用户创建基础对象,然后尝试撤消该操作,则不会删除该基础对象。相反,可以删除一个或多个子对象。显然,这种行为是不可预测的,是不需要的 因此,我尝试在默认情况下禁用撤消注册

我正在开发一个核心数据应用程序,它有一个相当大的托管对象层次结构,类似于树

创建基础对象时,它会创建几个子对象,这些子对象又会创建自己的子对象,依此类推。每个子对象都可以使用NSURLConnections收集信息

现在,我想在managedObjectContext中使用undoManager支持undo/redo。问题是,如果用户创建基础对象,然后尝试撤消该操作,则不会删除该基础对象。相反,可以删除一个或多个子对象。显然,这种行为是不可预测的,是不需要的

因此,我尝试在默认情况下禁用撤消注册。在managedObjectContext中修改任何内容之前,我通过调用
disableUndoRegistration:
来实现这一点。然后,在基本操作(如创建基本对象)之前启用撤消注册,然后在之后再次重新禁用注册

现在,当我尝试撤消时,出现以下错误:

撤消:NSNDOManager 0x1026428b0处于禁用状态 无效状态,已使用调用撤消 嵌套撤消组太多


想法?

nsondomanager等待下一个运行循环周期,直到它注册您的更改

// do your stuff

// give the run loop a breath

[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]];
[undoManager disableUndoRegistration];

这个问题发布已经一年多了,但无论如何,这里有一个答案:

你应该查看苹果的文档,上面写着:

撤消消息关闭最后打开的撤消组,然后应用该组中的所有撤消操作。。。如果调用undo时堆栈上存在任何未关闭的嵌套undo组,则会引发异常。要撤消嵌套组,必须使用endUndoGrouping消息显式关闭该组,然后使用undoNestedGroup撤消该组。


我与
NSUndoManager的交集处于无效状态,使用太多嵌套的撤销组调用了撤销
未涉及CoreData,但我的答案可能仍然有用

在我的例子中,由于在调用NSUndoManager-undo的过程中引发了代码中的未捕获异常,因此引发了undo manager异常

通过控制台回过头来,我可以看到我的应用程序代码异常和undo manager的NSInternalInconsistencyException

我使用了默认的runloop undo group行为,没有显式地将我的undo注册分组