Re: Dependent values that are not iVars
Re: Dependent values that are not iVars
- Subject: Re: Dependent values that are not iVars
- From: Quincey Morris <email@hidden>
- Date: Fri, 18 Dec 2009 11:08:49 -0800
On Dec 18, 2009, at 10:20, Paul Bruneau wrote:
> I am setting up the object that holds the dependent value as an observer of the individual members of the collection like this:
>
> [theFrameModule addObserver:self forKeyPath:kOverallWidth options:NSKeyValueObservingOptionNew context:NULL];
>
> And I use the following to see when one of the items in the collection has changed:
>
> - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
> {
> if ([keyPath isEqualToString:kOverallWidth]) {
> NSLog(@"got notification that overallwidth changed: %@", object);
> }
> }
>
>
> This works just fine. I get notified of the changes to the members of the collection.
>
> But my question is this:
>
> I want my dependent value to exist very simply as a method. I don't need or want it to be an ivar of its object. So something like this:
>
> -(NSInteger)overallWidth;
> {
> NSInteger overallWidthSubtotal = 0;
> for ( SLFrameModule * theModule in [self frameModules] )
> {
> overallWidthSubtotal += [theModule overallWidth];
> }
>
> return overallWidthSubtotal;
> }
>
> My problem is that when I use overallWidth in a binding, the value does not get updated. There is some "tickle" that is not occurring.
This is a situation where you use willChangeValueForKey:/didChangeValueForKey:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:kOverallWidth]) {
[self willChangeValueForKey:@"overallWidth"];
NSLog(@"got notification that overallwidth changed: %@", object);
[self didChangeValueForKey:@"overallWidth"];
}
}
A couple of things I notice:
1. You have 2 identically named properties ("overallWidth") in related objects. My experience has been that if there's ever anything wrong with (say) your bindings, it gets incredibly confusing working out from logged error messages *which* property has the problem. You can save yourself some grief by renaming (say) your dependent property to (say) "overallWidthSubtotal".
2. Your observer method is stripped down, right? You are really using a unique value for the context parameter, right? It's not really safe to just not care.
3. Your dependent property is *also* dependent on the array itself. You will also put the willChange/didChange invocations in the place(s) where you add/remove/replace objects in the underlying array, yes?
4. The use of willChange/didChange in the observer method causes a nested KVO notification. (It triggers at the didChange invocation.) In general, you have to be a little careful that your observer method puts your object in an internally consistent state before triggering the notification, and that you don't cause any infinite notification loops. This is likely not a problem if this is all your code, but it's something to keep in mind. (Actually, it's a potential issue anywhere you trigger a nested notification, such as when you set a property inside a different property setter method.)
_______________________________________________
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