Benedict's Soapbox

EMKKVOSelector: Adding selector callbacks to KVO

Key-value observing is a mechanism that allows objects to be notified of changes to specified properties of other objects.

The KVO mechanism is widely used in Foundation and AppKit (less so in UIKit). I frequently use it when working with NSOperations to observe isFinished. My biggest gripe with KVO is that all KVO changes are sent to one method, observeValueForKeyPath:ofObject:change:context:. The implementation of this method often becomes a ugly mass of if-else statements.

In an attempt to do away with observeValueForKeyPath:ofObject:change:context: I have written an NSObject category which augments KVO. It has three methods:

@interface NSObject (EMKKVOSelector)

-(void)EMK_addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath selector:(SEL)observationSelector;  
-(void)EMK_addObserver:(NSObject *)anObserver forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context selector:(SEL)observationSelector;  
-(void)EMK_removeObserver:(NSObject *)anObserver withKeyPath:(NSString *)keyPath selector:(SEL)observationSelector;  

@end

The selectors used for observationSelector must match one of the following method signatures:

-(void)noArguments
-(void)oneArgument:(NSString *)keyPath  
-(void)twoArguments:(NSString *) object:(id)  
-(void)threeArguments:(NSString *) object:(id) change:(NSDictionary)  
-(void)fourArguments:(NSString *) object:(id) change:(NSDictionary) context:(void *)  

eg:

-(void)refreshView;  
-(void)refreshCellValue:(NSString *)keyPath representingPersonObject:(id)person;  

All invocations to EMK_addObserver... methods must be balanced with a call to EMK_removeObserver.... These methods are not compatible with the standard KVO methods.

Download (from GitHub - the files are part of my open source library)

The code has only been briefly tested. Internally the code uses associate references and properties so it’s strictly Objective-C 2.0. Other people have implemented similar KVO fixes all of which offer slightly different features: