Re: Strategy for acting on changes in child objects?
Re: Strategy for acting on changes in child objects?
- Subject: Re: Strategy for acting on changes in child objects?
- From: BJ Homer <email@hidden>
- Date: Thu, 7 May 2009 00:27:41 -0600
On Wed, May 6, 2009 at 11:55 PM, Graham Cox <email@hidden> wrote:
>
>
> I could be wrong, but I don't think this is possible. However, I have
> solved this by minimising the tedium of having to register for all those
> individual property observations as follows:
>
> A. each observable object class exports a list of properties that it thinks
> may be of interest to an observer. This is just an array of strings
> (property names) returned by a class method.
>
> B. A utility method iterates over that list and registers a nominated
> observer against each one. There is also a complementary de-observing
> method.
>
> C. The observer calls the utility method on the child passing itself as an
> observer.
>
> For the observer, this reduces to one line to observe everything. The
> utility methods only need to be written once also, perhaps as an NSObject
> category. The remaining tedium is returning the list of properties from each
> observable class, but it turns out to be pretty quick and easy using
> [NSArray arrayWithObjects:]. You just have to remember to add the name to
> the list any time you add a property to the object. Subclasses should extend
> the list provided by their superclass.
>
> There may well be an easier solution but this works well for me. Relying on
> a keypath being passed through your parent is a bit fragile, since if
> anything changes a child property directly, your parent won't see it. Using
> KVO prevents that problem.
>
> --Graham
>
> You could also use some of the runtime functions [1] to get the names of
every property of an instance. class_copyPropertyList() would be your first
stop. You could then write a method (perhaps in a category on NSObject?)
that found all properties on a given object, and registered as an observer
for each of them. It would look something like:
- (void) addObserver:(id)anObserver forAllPropertiesWithOptions:(
NSKeyValueObservingOptions)theOptions context:(void *)theContext
{
unsigned int propertyCount = 0;
objc_property_t * propertyList = class_copyPropertyList([self class],
&propertyCount);
for (int i=0; i<propertyCount; ++i) {
const char *propertyName = property_getName(propertyList[i]);
NSString *propString = [NSString stringWithCString:propertyName encoding:
NSUTF8StringEncoding];
[self addObserver:anObserver forKeyPath:propString options:theOptions
context:theContext];
}
}
Note that I have not actually compiled the above code. I believe it to be
fairly close to something that would work, but make no guarantees.
-BJ Homer
[1]
http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
_______________________________________________
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