One Quickie

Using KVO for whole-object observation (Bindings->General)
I've got an object that has a bunch of individual attributes that are controlled by an inspector, and another object (a view that holds that object) which needs to redraw when something changes in the object, but it doesn't care which individual attribute it is. Rather than having the view observe each of the individual attributes, KVO provides a way to automatically trigger another observation when any dependent attribute changes.

First, in the +initialize for the class that's going to be observed:

+ (void) initialize
    NSArray *keys;
    keys = [NSArray arrayWithObjects: @"showMajorLines", @"minorWeight",
                    @"minorColor", @"minorWeightIndex", @"minorColorIndex",
                    @"majorWeightIndex", @"majorColorIndex", nil];

        setKeys: keys
        triggerChangeNotificationsForDependentKey: @"gridAttributeChange"];

} // initialize
So now when "showMajorLines" changes, "gridAttributeChange" will also be observed. KVO requires there actually must exist a gridAttributeChange method (or ivar I presume) before it'll do the notification to observing objects, so there needs to be a do-nothing method:
- (BOOL) gridAttributeChange
    return (YES);
} // gridAttributeChange
So now the view can do this:
- (void) setGridAttributes: (BWGridAttributes *) a
    [attributes removeObserver: self
                forKeyPath: @"gridAttributeChange"];

    [a retain];
    [attributes release];
    attributes = a;

    [a addObserver: self
       forKeyPath: @"gridAttributeChange"
        options: NSKeyValueObservingOptionNew
        context: NULL];

} // setGridAttributes
And will get updated whenever an individual attribute changes.

borkware home | products | miniblog | rants | quickies | cocoaheads
Advanced Mac OS X Programming book