Re: Model objects to NSUndoManager--am I doing it right?
Re: Model objects to NSUndoManager--am I doing it right?
- Subject: Re: Model objects to NSUndoManager--am I doing it right?
- From: Graham Cox <email@hidden>
- Date: Fri, 21 Aug 2009 01:27:17 +1000
On 21/08/2009, at 1:18 AM, Graham Cox wrote:
On 20/08/2009, at 5:17 AM, Paul Bruneau wrote:
In summary, it seemed like a Long Way to Go just to let my new
Entrance objects know who their document is. In my future is the
fact that Entrances will have FrameModules, which may contain a
Door, which will contain an array of Cutouts and so I am looking at
3-4 more generations of Model object types, each of which must a
similar way to get to the Document's Undo Manager.
Is this the right way?
This can be awkward, it's true.
The most general way I've found to handle this is to give each
object in a tree of objects a back pointer to its owner or
container. Naturally this back pointer mustn't be retained or you'll
get a retain cycle, but any time you add an object to another, the
added object's back pointer is set. The top level object's back
pointer points to the document, or top level controller which owns
it, and so there is a path from any object to the root, which has an
undo manager. Then it's a simple matter to give any object its own -
undoManager method (which always merely invokes its owner's -
undoManager method, and so on).
I'd also take issue with the code you posted. As an IBAction method,
it should probably not be setting up the undo task. Instead it
should just set the relevant property(s) of the object it's dealing
with, and those property methods should do the necessary with the
undo manager. The action method is a good place to set the action
name though. This way if there are several steps involved in doing
something, like setting a series of properties, all the steps get
undone as needed. It also means that properties are inherently
undoable, and code from anywhere can call them and be undoable. In
your example, if code calls -removeObject: directly, it won't be
undoable.
Oh, another thing I forgot to mention which could well be highly
relevant to your situation, if you're using an NSArrayController as
your top level "owner" object. You can leverage KVO to handle undo as
well. To do this, you need to KV-observe any properties you want to
undo. When you get the change notification, you need to prepare an
invocation as usual, but it can be a generic one that records the
target object, keypath and old value of the property, with a selector
that is always the same. When the task is undone, the general selector
is invoked and you can then use KVC to change the property of the
target object back again. It's a nice generic way to handle it, with
the downside that comes with the various pitfalls of KVO - i.e. making
sure you stop observing stuff when you should.
Hillegasse explores this approach in his book BTW.
--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