October 07, 2006
From the NSUndoManager documentation:
All individual undo operations before a subsequent endUndoGrouping message are grouped together and reversed by a later undo message. By default undo groups are begun automatically at the start of the event loop, but you can begin your own undo groups with this method, and nest them within other groups.
I noticed this behavior for the first time today when adding objects from one collection to another, which happened to register a new undo action for each object. Since this was all done in a single pass through the run loop, NSUndoManager was smart enough to group these actions into a single undo operation.
There’s nothing wrong with this; for most situations it’s going to produce the correct result. When the user clicks a button or hits a key, it’s natural to expect that command will make one entry in the undo stack, even if your application performs several tasks behind the scenes. For the programmer, it can be a big time saver. You can register your undo action in an accessor method or through key-value observation, and not really worry about what triggered that change. The change could be part of some larger, more complex action, but you don’t need to worry about that, NSUndoManager will handle grouping by itself. Of course, if you really do want to break it down into multiple undo actions, it’s just one extra line of code. Neat!