bdunagan

Brian Dunagan

December 6 2008
Key-value observing uses paths, not data

Although I've been using Cocoa Bindings for a bit now, I just recently realized how key-value observing (KVO) works. It observes paths, not data. For example, let's say I have NSString *foo in Bar class. Other classes can get the value with [bar valueForKeyPath:@"foo"]. But if I can set the value with foo = @"123", the change doesn't propagate. Only by calling [self setFoo:@"123"] is KVO leveraged. See Apple's documentation for more information.

Morever, what the getter/setter methods actually do is irrelevant from the observer's perspective. What's important is that whenever the setter is called, any interface elements observing that path are alerted, and they call the getter next. So, as a simple example, below is a class for displaying the date. An NSTimer calls setDate: every second, but that method doesn't actually do anything. Callling that setter method can be a quick way to alert the interface that the underlying data has changed, even if the setter is not the method changing it.

#import <Cocoa/Cocoa.h>

@interface Bindings : NSObject {
	IBOutlet NSTextField *dateField;
	NSString *date;
}

@property (readwrite) NSString *date;

@end

@implementation Bindings

@synthesize date;

- (void)awakeFromNib
{
	[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(setDate:) userInfo:nil repeats:YES];
}

- (NSString *)date
{
	return [[NSDate date] description];
}

@end

To see this code work, go to Interface Builder and drop in an NSTextField. Hook up the Bindings like you see below.

Below is the result.

NSProgressIndicator in NSTableView or NSOutlineView PackageMaker tips
LinkedIn GitHub Email