Use blocks to observe Objective-C properties using KVO
C Objective-C
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
KVOBlockBinding
KVOBlockBindingExample.xcodeproj
KVOBlockBindingExample
KVOBlockBindingTests
.gitignore
LICENSE.md
README.md
WSKVOBlockBinding.vendorspec

README.md

Bind blocks to properties using KVO

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.

Refactor Safe Keypaths

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];
 }];

License

Contains code from libextobjc

Released under the MIT License. See the LICENSE file for more information.