Re: Core Data and undo action names
Re: Core Data and undo action names
- Subject: Re: Core Data and undo action names
- From: "John C. Randolph" <email@hidden>
- Date: Mon, 22 Aug 2005 19:40:27 -0700
Oops, forgot to send this to the list..
On Aug 22, 2005, at 4:21 AM, Bill Cheeseman wrote:
I have just completed the task of implementing meaningful undo
action names
in my Core Data application. For the most part it was
strightforward. I just
invoke -setActionName: in each setter or other method that changes
a Core
Data value.
But one situation was hard, and I wonder if there is a simple way to
generalize it.
Some operations not only change a value directly but also trigger
secondary
changes. In such a case, the undo action name should describe the
initiating
operation, not the secondary changes, and undoing it will
automatically
reverse all the secondary changes. But if the secondary changes are
accomplished through setters that invoke -setActionName: (because
sometimes
these setters are invoked directly as an initiating operation), the
initiating operation's undo action name gets replaced by the secondary
change's undo action name. Whichever secondary change happens last
wins.
In some cases, I have overcome this by disabling undo registration
in the
observer and, in the secondary setter, testing whether undo
registration is
enabled. That's pretty easy. But in other cases the observer is Cocoa
bindings and I don't have immediate access. As a result, I have to
think
through the logic for each secondary setter independently and devise a
special test before invoking -setActionName:. That is very hard,
time-consuming, and error-prone.
Is there a better way?
I'm not sure about "better", but what springs to my mind would be
something like this..
@interface ActionNameSetter : NSObject
{
NSString *actionName;
NSUndoManager *undoManager
}
@end
@implementation ActionNameSetter
- setActionName:aName undoManager:aManager // first time wins,
subsequent attempts are discarded
{
undoManager = aManager;
if (!actionName) actionName = [actionName retain];
[self performSelector:@selector(flush) afterDelay:0 cancelPrevious:YES];
}
- flush
{
[undoManager setActionName:actionName];
[actionName release];
actionName = nil;
}
@end
And then in your accessors, instead of sending -setActionName: to the
undo manager, you'd send it to this "first one wins" helper object
instead.
-jcr
John C. Randolph <email@hidden> (408) 914-0013
Roaming Cocoa Engineer,
Available for your projects at great Expense and Inconvenience.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden