NSUndoManager, Core Data and selective undo/redo
I'm working on a core data application that has a rather large hierarchy of managed objects similar to a tree.
When a base object is created, it creates a few child objects which in turn create their own child objects and so on. Each of these child objects may gather information using NSURLConnections.
Now, I'd like to support undo/redo with the undoManager in the managedObjectContext. The problem is, if a user creates a base object, then tries to undo that action, the base object is not removed. Instead, one or more of the child objects may be removed. Obviously this type of action is unpredictable and unwanted.
So I tried disabling undo registration by default. I did this by calling disableUndoRegistration: before anything is modified in the managedObjectContext. Then, enabling undo registration before base operations such as creating a base object the again re-disabling registrations afterwords.
Now when i try to undo, I get this error:
undo: NSUndoManager 0x1026428b0 is in invalid state, undo was called with too many nested undo groups
NSUndoManager waits for the next run loop cycle until it registers your changes
// do your stuff // give the run loop a breath [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:[NSDate date]]; [undoManager disableUndoRegistration];
More than a year since this question was posted but anyway here's a answer:
Your should check out apple's Documentation it says:
.. The undo message closes the last open undo group and then applies all the undo operations in that group ... If any unclosed, nested undo groups are on the stack when undo is invoked, it raises an exception. To undo nested groups, you must explicitly close the group with an endUndoGrouping message, then use undoNestedGroup to undo it.
My intersection with NSUndoManager is in invalid state, undo was called with too many nested undo groups did not involve CoreData however my answer may be useful none the less.
In my case this the undo manager exception was raised due to an uncaught exception in my code that was raised during a call to NSUndoManager -undo.
Looking back through the console I could see both my app code exception and the undo manager's NSInternalInconsistencyException.
I used the default runloop undo group behaviour and did not explicit group my undo registrations.