views:

209

answers:

3

I am smitten by KVC/KVO. Super powerful. There is one problem though. I'm trying to be true the the MVC etho but I see no way to use an observation pattern to monitor the allocation or deallocation of an Objective-C class instance.

This is actually important as I have a model with fine-grained internal messaging that I want to observe from a controller (or delegate). The stumbling block for me is I don't see how, external to the model, I can remove an observer for a sub-component that is about to be deallocated without the controller knowing about the internal logic of the model which would compromise encapsulation.

Can someone suggest an approach for this scenario.

Thanks, Doug

A: 

I think you'll have to post the notifications yourself, unless you use something like CoreData. If you're using CoreData, NSManagedObject (the root class of all stored CoreData objects) has an -awakeFromInsert method that gets called after the object has been created and inserted into the ManagedObjectContext.

As for destruction, you could probably just post a notification right as you enter the -dealloc method.

Dave DeLong
A: 

I'm not sure exactly what you're trying to achieve, so a little more explanation would be good.

If you just want to remove an observer before the observed object gets deallocated, then don't worry, because KVO will handle it. Even if you're using notifications it won't cause a problem, you just won't receive any notifications from the object.

If you're trying to observe multiple objects (e.g. an array of Widgets), and would like to know when an object is added or deleted, KVO can handle that too. You just have to make the array a key on your model object, and observe it with KVO. You also have to modify the array in a KVO compliant way (e.g. mutableArrayForKey:, or use your own willChangeValueForKey and didChangeValueForKey).

Tom Dalling
Thanks Tom. Very helpful as well. Cheers.
dugla
+4  A: 

Doug - there really isn't enough information in your description to know what it is you are doing and how to best (or if it is appropriate at all) apply KVO to the problem.

KVO is all about observing properties on objects. You typically shouldn't care when they are created or destroyed except insofar as you must stop observing them before they are destroyed.

You should instead start and stop observing objects when those objects become interesting to you. Consider a graphics drawing package where a document has an ordered array of shapes, and you are interested in observing the backgroundColor property of each shape.

We wouldn't try to observe the instantiation and deallocation of the Shape instance, but instead we observe the "shapes" property on the document. Through that observer, we can determine when a shape is added to, or removed from, the document. When a shape is added to the document, we start observing it. When it is removed from the document, we stop observing it. (Note that it may be removed from the document but not deallocated, if it is on the undo stack, etc.)

In the object graph for your model, to use KVO you'll want to add and remove the objects from your object graph in a KVO compliant way so you can observe the relationship mutations, and in that observer, start and stop property observers on the related objects.

Jim Correia
You nailed it Jim. Thanks for the clarifying. I completely ignored the fact that it is the ivar refering to the instance of the object I should be observing not the instance itself. And further, using dot syntac - grandparent.parent.child - I can observe anything in the object graph.I assume there is a KVO pattern for observing collections, yes?2 thumbs up Jim.-Doug
dugla
You observe the property for the relationship. In my drawing application, you would observe the "shapes" property.As the implementor of the document object, I need to make sure everytime I mutate the _shapes ivar, I do so in a KVO compliant way.Read through NSKeyValueObserving.h to see what KVO notifications you should wrap mutation of the relationship in, and what information you can expect to see in your observer callback when such mutations are made.
Jim Correia