views:

127

answers:

2
- (void)cancel {
//   [managedObjectContext.undoManager disableUndoRegistration];
     [managedObjectContext deleteObject:object]; // I don't want this deletion to be recorded on the undo stack which is empty at this point.
//   [managedObjectContext.undoManager enableUndoRegistration];
     [managedObjectContext.undoManager removeAllActions];
}

With this code, I still got the deletion on the undo stack, even uncommenting those two lines can not prevent the recording. Why?

A: 

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).

Matthew
1. A button triggers -cancel.2. How can I find whether undo stack is empty except trying to do an undo? This info is encapsulated so I can not log.3. My "undo" does trigger an action that undoes my deletion.4. nil undo manager? Oh, no, of course. But thanks for the reminding.
an0
+1  A: 

You'll need to call -processPendingChanges on the managed object context before disabling and before re-enabling undo processing. Core Data delays registering undo events until processPendingChanges to allow for coalescing multiple changes to the same attribute and similar shortcuts.

Fnord