Key-value Observer (KVO) on the iPhone

key_value_observing_imgHere’s one for the you-learn-something-new-every-day file. Objective C supports a key-value-observer model that lets you monitor changes on an object’s property values. Unfortunately, I found this out the hard way while working on a MKMapKit project.

What I wanted to do seemed simple: have a map view with a bunch of moving objects on it. Each object pulls its current position from an XML document on the web. I already had my XML-wrapper object written when I wanted to display it on the map, so I simply implemented the MKAnnotation protocol. All of my objects appeared, and all seemed to be right with the world.

Then, I started updating my objects and found that the annotations didn’t move. At all. I found a bunch of people on the web trying to solve the same problem, but I wasn’t very happy with the solutions I found. Most of them involved removing the annotations and adding them back into the map view. But, thankfully, I found one article that mentioned KVO on the iPhone. I was pretty familiar with KVO from my Flex projects, but didn’t even realize it was supported in Objective C.

To make a long story short, if you don’t use the willChangeValueForKey and didChangeValueForKey before and after updating your coordinate property on your annotation object, the MKMapView will not be aware that it has moved. After bracketing my XML update code with those two calls, all of a sudden my annotations started moving around.

-(void)setXmlProperty:(NSString *)newXml
        [self willChangeValueForKey:@"coordinate"];
        [_xmlProperty release];
        _xmlProperty = [newXml retain];
        [self didChangeValueForKey:@"coordinate"];