Created by Jamz Tang at 16 July 2013
There have been a good number of attempts solving the "broken" Key Value Observing official API.
And we get solutions like custom notification centre replacement, extra target-action based observation, handly marcos, trampoline...?, mixin context for selector, wah, and one that can't even find the link to the repo, etc.
But come on, just because I need to subclass one 3rd party library that already implements the -[NSObject observeValueForKeyPath:ofObject:change:context:]
... all I want is a tiny wrapper that allows me stay away from that method.
I don't want any overheads to the base NSObject due to custom category methods; I don't want solutions hacking around with associative objects, I just want a just enough solution for that particular hassle, please...
/*
* This file is part of the http://ioscodesnippet.com
* (c) Jamz Tang <jamz@jamztang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/*
* Usage:
*
* // Create a property
* @property (nonatomic, strong) JTKeyValueObserver *keyObserver;
*
* // Just use the initializer, and you don't need to deregister any observers
* // because the wrapper does it for you when it's released
*
- (void)viewDidLoad {
[super viewDidLoad];
self.keyObserver = [[JTKeyValueObserver alloc] initWithObject:self
keyPath:@"state"
option:NSKeyValueObservingOptionNew
context:nil
handlerBlock:^(NSObject *object, NSString *keyPath, NSDictionary *change, void *context) {
NSLog(@"%@", [object valueForKeyPath:keyPath]);
}];
}
*/
#import <Foundation/Foundation.h>
typedef void(^JTKVOHandler)(NSObject *object, NSString *keyPath, NSDictionary *change, void *context);
@interface JTKeyValueObserver : NSObject
- (id)initWithObject:(__weak NSObject *)object
keyPath:(NSString *)keyPath
option:(NSKeyValueObservingOptions)options
context:(void *)context
handlerBlock:(JTKVOHandler)handler;
@end
/*
* This file is part of the http://ioscodesnippet.com
* (c) Jamz Tang <jamz@jamztang.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "JTKeyValueObserver.h"
@interface JTKeyValueObserver ()
@property (nonatomic, copy) NSString *keyPath;
@property (nonatomic, copy) JTKVOHandler handlerBlock;
@property (nonatomic, unsafe_unretained) NSObject *object; // Weak property released before dealloc kicks in, but we don't really want to retain the owner
@end
@implementation JTKeyValueObserver
- (id)initWithObject:(__weak NSObject *)object
keyPath:(NSString *)keyPath
option:(NSKeyValueObservingOptions)options
context:(void *)context
handlerBlock:(JTKVOHandler)handler {
self = [super init];
if (self) {
self.keyPath = keyPath;
self.object = object;
self.handlerBlock = handler;
[object addObserver:self
forKeyPath:keyPath
options:options
context:context];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (self.handlerBlock) {
self.handlerBlock(self.object, keyPath, change, context);
}
}
- (void)dealloc {
[self.object removeObserver:self forKeyPath:self.keyPath];
}
@end
To remove observer earlier? Just nil the properly, you probably already knew ;P
Using CocoaPods: [?]
pod 'JTKeyValueObserver', '~> 0.0.1'
Clone this repository:
git clone git://gist.github.com/6009092.git JTKeyValueObserver
If you think this is useful, share this article with your friends :)
blog comments powered by DisqusUINibDecoderProxy Observes what's encoded in an NSCoder object
JTKeyValueObserver Revisiting KVO+Block, the simplest version.
MethodSwizzle Method Swizzling in Objective-C
UITableViewDeleteActionResponder Quick hack to enable delete menu item in UITableView menuController
UIApplicationAddition Quickly switch supported UIInterfaceOrientation for your View Controllers
JTTargetActionBlock Adding Block support for UIControl's Target-Action mechanism
NSArray-JTArraySplit Splitting an array to several components
UIImage+JTImageDecode Force decompressing UIImage in background to achieve better performance
UINavigationBar-JTDropShadow Adding drop shadow on UINavigationBar (before iOS 6)
UIImage-JTImageCrop Crop an image in specific rect
UIView+JTRemoveAnimated Adding fadeout effect to any -[UIViews removeFromSuperview]
JTStringAddition NSStringf. Simpler printf styled +[NSString stringWithFormat:]
UIView-JTViewToImage Rendering any UIViews into UIImage in one line (updated with iOS 7 support)
NSObject-JTNibLoader Loading a Nib file programmatically using NSObject category
UIImage-JTColor Creating a placeholder UIImage dynamically with color
NSObject-JTCancelableScheduledBlock Cancelable Scheduled Blocks in Objective-C