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 (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