Skip to content

Instantly share code, notes, and snippets.

@Tricertops
Last active December 24, 2015 22:49
Show Gist options
  • Select an option

  • Save Tricertops/6875536 to your computer and use it in GitHub Desktop.

Select an option

Save Tricertops/6875536 to your computer and use it in GitHub Desktop.
Simplest KVO using blocks. You don't have to use ReactiveCocoa to blockify KVO.
#import <Foundation/Foundation.h>
typedef void(^KVObservingBlock)(id value, NSDictionary *change);
@interface KVObserver : NSObject
- (instancetype)initWithBlock:(KVObservingBlock)block;
@end
#import "KVObserver.h"
@interface KVObserver ()
@property (nonatomic, readwrite, copy) KVObservingBlock block;
@end
@implementation KVObserver
- (instancetype)initWithBlock:(KVObservingBlock)block {
self = [super init];
if (self) {
NSCParameterAssert(block != nil);
self.block = block;
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
id value = [object valueForKeyPath:keyPath];
self.block(value, change);
}
@end
self.titleObserver = [[KVObserver alloc] initWithBlock:^(NSString *title, NSDictionary *change) {
NSLog(@"Doing it right! %@", title);
}];
[self addObserver:self.titleObserver forKeyPath:@"title" options:NSKeyValueObservingOptionInitial context:NULL];
// Later that day...
[self removeObserver:self.titleObserver forKeyPath:@"title"];
// Do it better.
@Tricertops

Copy link
Copy Markdown
Author

The next thing you should do is -[KVObserver observeObject:keyPath:]. Default options (choose yours), no context. Weakly store object and copy key-path for later removing using -[KVObserver remove]. Optionaly store multiple pairs weakly using NSMapTable.

@Tricertops

Copy link
Copy Markdown
Author

Also, to avoid strings, use @keypath macro:

#define keypath(object, path)     (((void)(NO && ((void)object.path, NO)), # path))

NSString *path = @keypath(self, title);

This will autocomplete the key-path, validate and refactor it (or at least will show error).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment