Created by Jamz Tang at 16 July 2013

Revisiting KVO+Block, the simplest version.

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


Installation

Using CocoaPods: [?]
pod 'JTKeyValueObserver', '~> 0.0.1'

Clone this repository:
git clone git://gist.github.com/6009092.git JTKeyValueObserver

Download | More...


If you think this is useful, share this article with your friends :)

blog comments powered by Disqus

ioscodesnippet.com