Re: NSUndoManager setActionName: oddity
Re: NSUndoManager setActionName: oddity
- Subject: Re: NSUndoManager setActionName: oddity
- From: Graham Cox <email@hidden>
- Date: Tue, 03 Jul 2012 09:59:27 +1000
On 03/07/2012, at 3:26 AM, Conrad Shultz wrote:
> I'll take a look at GCUndoManager. I'd heard of it being used in the context of Core Data, but maybe I should consider it here too. (I hate to introduce third-party dependencies unless absolutely necessary.)
It wasn't written with Core Data in mind, but some later fixes were made to ensure it did work with Core Data.
> I could set the action name in the model too, but that feels icky. (Do you set the action name or just register undo operations in the model? I don't see why action names would be needed for scripting, but then again I don't really know AppleScript.)
I think your original approach is close to optimal practice; I follow this pattern almost always:
- (IBAction) someAction:(id) sender
{
[self dotheActualActionWithUndo];
[[self undoManager] setActionName:[sender title]];
}
There's no reason to check whether the undo manager is undoing - at this point it can't possibly be. All the interaction with the undo manager takes place in the internals of the controller or data model - the undo manager will never (or should never) invoke an action method. Undo is never invoked on a thread other than main.
The undo manager is given the various tasks to do first, then the action name is set last. This takes care of ensuring that the undo manager has something it can attach the name to. I think this is the only reason you are having problems.
The action name is taken from the title of the sender (e.g. button or menu item). Why do this? Because it's one less bit of text to localize and the action appearing in Undo is fully consistent with the text in the interface. There are sometimes exceptions to this approach that mean you have to explicitly set an action name, but they shouldn't be common.
The action name should be set at the end of the highest level method that causes the undoable work to happen. Then, if the operation consists of several steps, each of which has some undoable component, the action name is attached to the entire group of operations. In the NSUndoManager, groups are marked internally using sentinel objects rather than an actual container of some sort, and the 'group open' marker is not added until there is a task ready to put in it. That means that if you try to set the action name first, there's nothing available to attach it to (NSUndoManager will attach it to the current group, but if there are no tasks, there's nothing there, and if there are, the group in question is the wrong one).
--Graham
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden