What is calling -cancel? I have encountered situations where some other method is registering an undo event (and core data may be "helpfully" doing this for you). You may find that your undo stack is empty at the end of -cancel but gets an event added by the calling method.
In these cases choosing "Undo" doesn't actually (un)do anything, the event has nothing to undo. To prevent these superfluous events you need to disable undo registration (and then reenable it) in the calling method. Something along the lines of...
- (void)doSomething {
// Disable undo until we definitely want to undo stuff
[managedObjectContext.undoManager disableUndoRegistration];
// Stuff goes here
if ( userCancelled ) {
[self cancel];
[managedObjectContext.undoManager enableUndoRegistration];
return;
}
// We actually want user to be able to undo the following stuff
[managedObjectContext.undoManager enableUndoRegistration];
// More stuff goes here
}
Before delving too far into this do some simple NSLog checks to see what is on the undo stack when (and to make sure you are sending messages to a real live NSUndoManager rather than a nil object).