Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // NSObject+KVO_Blocks.m
- //
- // Created by Jonathan Annett on 1/11/13.
- // Copyright (c) 2013 Sophtwhere. All rights reserved.
- //
- #import "NSObject+KVO_Blocks.h"
- #import "NSObject+arcAgnostics.h"
- #import <objc/runtime.h>
- @implementation NSObject (KVOBlocks)
- - (void)addObserverForKeyPath:(NSString *)keyPath
- options:(NSKeyValueObservingOptions)options
- context:(void *)context
- withBlock:(KVOBlock)block
- {
- CFTypeRef key = CFBridgingRetain(keyPath);
- NSMutableArray *observers = (__bridge NSMutableArray*) objc_getAssociatedObject(self, key);
- if (observers) {
- [observers addObject:Block_copy(block)];
- } else {
- observers = [[NSMutableArray alloc] initWithObjects:Block_copy(block), nil];
- objc_setAssociatedObject(self, key, (__bridge NSMutableArray*) observers, OBJC_ASSOCIATION_ASSIGN);
- }
- [self addObserver:self forKeyPath:keyPath options:options context:context];
- CFBridgingRelease(key);
- }
- - (void)observeValueForKeyPath:(NSString *)keyPath
- ofObject:(id)object
- change:(NSDictionary *)change
- context:(void *)context
- {
- CFTypeRef key = CFBridgingRetain(keyPath);
- NSMutableArray *observers = (__bridge NSMutableArray*) objc_getAssociatedObject(self, key);
- CFBridgingRelease(key);
- if (observers) {
- NSInteger ix = 0;
- while (ix < observers.count) {
- KVOBlock locateBlock = [observers objectAtIndex:ix];
- locateBlock(keyPath,[(id)self objectForKey:keyPath],change,context);
- ix ++;
- }
- }
- }
- - (void)removeBlock:(KVOBlock)block observerForKeyPath:(NSString *)keyPath
- {
- CFTypeRef key = CFBridgingRetain(keyPath);
- NSMutableArray *observers = (__bridge NSMutableArray*) objc_getAssociatedObject(self, key);
- CFBridgingRelease(key);
- if (observers) {
- if (block) {
- NSInteger ix = 0;
- while (ix < observers.count) {
- KVOBlock locateBlock = [observers objectAtIndex:ix];
- if (locateBlock==block) {
- Block_release(locateBlock);
- [observers removeObjectAtIndex:ix];
- } else {
- ix ++;
- }
- }
- } else {
- while (observers.count>0) {
- KVOBlock locateBlock = observers.lastObject;
- Block_release(locateBlock);
- [observers removeLastObject];
- }
- }
- if (observers.count==0) {
- objc_setAssociatedObject(self,key, nil, OBJC_ASSOCIATION_COPY);
- [self removeObserver:self forKeyPath:keyPath];
- [observers release];
- }
- } else {
- [self removeObserver:self forKeyPath:keyPath];
- }
- CFBridgingRelease(key);
- }
- @end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement