.h 文件
- #import <Foundation/Foundation.h>
- typedef void (^LGFKVOBlock)(NSDictionary *change, void *context);
- @interface NSObject (LGFKVOBlocks)
- #pragma mark - 给某个 NSObject 注册 KVO 监听 使用 block 进行回调
- /**
- @param observer 监听对象
- @param keyPath 监听 属性 key 值
- @param options NSKeyValueObservingOptions
- @param context 附带内容
- @param block block 回调
- */
- + (void)lgf_AddObserver:(NSObject *)observer
- forKeyPath:(NSString *)keyPath
- options:(NSKeyValueObservingOptions)options
- context:(void *)context
- withBlock:(LGFKVOBlock)block;
- #pragma mark - 删除某个 NSObject 的 KVO BLOCK 监听
- /**
- @param observer 监听对象
- @param keyPath 监听 属性 key 值
- */
- + (void)lgf_RemoveBlockObserver:(NSObject *)observer
- forKeyPath:(NSString *)keyPath;
- #pragma mark - 给自己注册 KVO 监听 使用 block 进行回调
- /**
- @param keyPath 监听 属性 key 值
- @param options NSKeyValueObservingOptions
- @param context 附带内容
- @param block block 回调
- */
- - (void)lgf_AddObserverForKeyPath:(NSString *)keyPath
- options:(NSKeyValueObservingOptions)options
- context:(void *)context
- withBlock:(LGFKVOBlock)block;
- #pragma mark - 删除自己的 KVO BLOCK 监听
- /**
- @param keyPath 监听 属性 key 值
- */
- - (void)lgf_RemoveBlockObserverForKeyPath:(NSString *)keyPath;
- @end
.m 文件
- #import "NSObject+LGFKVOBlocks.h"
- #import "LGFOCTool.h"
- @implementation NSObject (LGFKVOBlocks)
- #pragma mark - 给某个 NSObject 注册 KVO 监听 使用 block 进行回调
- /**
- @param observer 监听对象
- @param keyPath 监听 属性 key 值
- @param options NSKeyValueObservingOptions
- @param context 附带内容
- @param block block 回调
- */
- + (void)lgf_AddObserver:(NSObject *)observer
- forKeyPath:(NSString *)keyPath
- options:(NSKeyValueObservingOptions)options
- context:(void *)context
- withBlock:(LGFKVOBlock)block {
- objc_setAssociatedObject(observer, (__bridge const void *)(keyPath), block, OBJC_ASSOCIATION_COPY);
- [self addObserver:observer forKeyPath:keyPath options:options context:context];
- }
- #pragma mark - 删除某个 NSObject 的 KVO BLOCK 监听
- /**
- @param observer 监听对象
- @param keyPath 监听 属性 key 值
- */
- + (void)lgf_RemoveBlockObserver:(NSObject *)observer
- forKeyPath:(NSString *)keyPath {
objc_setAssociatedObject(observer, (__bridge const void *)(keyPath), nil, OBJC_ASSOCIATION_COPY);
- [self removeObserver:observer forKeyPath:keyPath];
- }
- #pragma mark - 给自己注册 KVO 监听 使用 block 进行回调
- /**
- @param keyPath 监听 属性 key 值
- @param options NSKeyValueObservingOptions
- @param context 附带内容
- @param block block 回调
- */
- - (void)lgf_AddObserverForKeyPath:(NSString *)keyPath
- options:(NSKeyValueObservingOptions)options
- context:(void *)context
- withBlock:(LGFKVOBlock)block {
- objc_setAssociatedObject(self, (__bridge const void *)(keyPath), block, OBJC_ASSOCIATION_COPY);
- [self addObserver:self forKeyPath:keyPath options:options context:context];
- }
- #pragma mark - 删除自己的 KVO BLOCK 监听
- /**
- @param keyPath 监听 属性 key 值
- */
- - (void)lgf_RemoveBlockObserverForKeyPath:(NSString *)keyPath {
objc_setAssociatedObject(self, (__bridge const void *)(keyPath), nil, OBJC_ASSOCIATION_COPY);
- [self removeObserver:self forKeyPath:keyPath];
- }
- + (void)load {
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- Class class = [self class];
- SEL observeValueForKeyPath = @selector(observeValueForKeyPath:ofObject:change:context:);
- SEL lgf_ObserveValueForKeyPath = @selector(lgf_ObserveValueForKeyPath:ofObject:change:context:);
[LGFAllMethod lgf_MethodReplaceWithClass:class selOne:observeValueForKeyPath selTwo:lgf_ObserveValueForKeyPath];
- });
- }
- - (void)lgf_ObserveValueForKeyPath:(NSString *)keyPath
- ofObject:(id)object
- change:(NSDictionary *)change
- context:(void *)context {
- LGFKVOBlock block = objc_getAssociatedObject(self, (__bridge const void *)(keyPath));
- block(change, context);
- }
- @end
分类中方法必须替换
[LGFAllMethod lgf_MethodReplaceWithClass:class selOne:observeValueForKeyPath selTwo:lgf_ObserveValueForKeyPath];
- #pragma mark - 运行时方法替换
- /**
- @param class 方法所属的类
- @param selOne 被替换的方法
- @param selTwo 替换的方法
- */
- + (void)lgf_MethodReplaceWithClass:(Class)class selOne:(SEL)selOne selTwo:(SEL)selTwo {
- Method met_One = class_getInstanceMethod(class, selOne);
- Method met_Two = class_getInstanceMethod(class, selTwo);
- BOOL didAddMethod =
class_addMethod(class, selOne, method_getImplementation(met_Two), method_getTypeEncoding(met_Two));
if (didAddMethod) {
class_replaceMethod(class, selTwo, method_getImplementation(met_One), method_getTypeEncoding(met_One));
- } else {
- method_exchangeImplementations(met_One, met_Two);
- }
- }
以上 新建类复制黏贴即可
来源: http://www.jianshu.com/p/fc3cd50292cb