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 (Cocoa-dev@lists.apple.com)

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to