Ray Yamamoto Hilton
Freelance Mobile Architect & iOS Developer in Melbourne, Australia
~

Block-Based Observations with KVO

Blocks in Objective-C have been a life-saver and allowed our code to become terser and more understandable. Although some of the main parts of the iOS SDK have block-based alternatives (animations, etc), KVO is still based on defining a method with a well-known signature in your observer (not even defined by a @protocol and doesn’t allow the use of arbitrary @selector). I felt there should be a way to be able to achieve this and the result is this project on github.

In order to encapsulate the observation, a new instance of an object that implements the callback method signature is created for each observation and passed back to the caller. It is expected that this object is retained by the caller until the caller wants the observation to end. I’m not totally convinced that this is the best pattern, but it is at least concise and uses the existing language semantics. So, on to a simple example:

1
2
3
4
5
6
7
// To add observation
self.label1Binding = [self.model addObserverForKeyPath:@"exampleValue1" block:^(NSDictionary *change) {
  label1.text = [NSString stringWithFormat:@"%d", self.model.exampleValue1];
}];

// To remove observation
self.label1Binding = nil;

As you can see, this is very terse and means that all the code to react to changing properties can be encapsulated in the one place. The returned value is being set to a retained property so that the binding does not get dealloc’d. This observation will remain in effect until you release the returned object by setting the property to nil (as in the example) or, indeed, set the property to any other binding.

I would be very interested in feedback about whether this works for you.