This repo contains a simple category, NSObject+WSObservation, and an example project. The category adds methods for observing a keypath using a block:
- (WSObservationBinding*)observe:(id)object
keyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
block:(WSObservationBlock)block;
- (WSObservationBinding*)observe:(id)object
keyPath:(NSString *)keyPath
block:(WSObservationBlock)block;
The observer is the receiver of the message. The object is the object to observe. The keyPath is the standard ObjectiveC of referencing properties within an object tree (e.g. @"some.path.to.property"). The options are the same as you would pass for the traditional KVO methods. The second method simply calls the first with the default observing options of NSKeyValueObservingOptionNew & NSKeyValueObservingOptionOld
To remove the bindings, there are three methods:
This will remove all observations on the specified object for the receiver of the message:
- (void)removeAllObservationsOn:(id)object;
This will remove all observations on the receiver on a specified object for a particular keypath:
- (void)removeAllObserverationsOn:(id)object keyPath:(NSString*)keyPath;
And this will remove ALL block-based observations on the receiver
- (void)removeAllObservations;
Also, unlike the normal addObserver methods for KVO, these ones return an object that can be stored (assign or weak) by the caller. This object has method, invalidate, which allows the caller to selectively remove a particular binding without affecting any others on the same object.
There is also an invoke method that will force the binding block to execute.
The example project shows a typical use case of binding a model object's properties to a couple of UILabels and using both invalidate and remove* methods to control observation.
The repo also contains code from Justin Spahr-Summers' libextobjc library to allow refactor safe keypaths. Using a string like @"some.path.to.property" could lead to issues when the property name changes and the compiler is not giving any warnings telling you that your KVO binding just broke.
[self observe:self keyPath:@keypath(self.value) block:^(ViewController* observed, NSDictionary *change) {
self.label.text = [NSString stringWithFormat:@"%f", observed.value];
}];
[self observe:self keyPath:@keypath(self, value) block:^(ViewController* observed, NSDictionary *change) {
self.label.text = [NSString stringWithFormat:@"%f", observed.value];
}];
[self observe:self keyPath:@keypath(self, container.value) block:^(MyObject* observed, NSDictionary *change) {
self.label.text = [NSString stringWithFormat:@"%f", observed.value];
}];
[self observe:self.container keyPath:@keypath(self.container, value) block:^(MyObject. observed, NSDictionary *change) {
self.containerLabel.text = [NSString stringWithFormat:@"%f", observed.value];
}];
Released under the MIT License. See the LICENSE file for more information.