.h
typedef void(^kvoBlock)(NSDictionary<NSKeyValueChangeKey,id> *dict);
@interface NSObject (YYKVO)
- (void)yyObserver:(NSObject *)object keyPath:(NSString *)keyPath block:(kvoBlock)block;
@end
.m
#import <objc/runtime.h>
typedef void(^deallocBlock)(void);
@interface YYKVOController : NSObject
/** */
@property (nonatomic, strong) NSObject *observerdObject;
/** */
@property (nonatomic, strong) NSMutableArray <deallocBlock> *blockArr;
@end
@implementation YYKVOController
- (NSMutableArray<deallocBlock> *)blockArr {
if (!_blockArr) {
_blockArr = [NSMutableArray array];
}
return _blockArr;
}
- (void)dealloc {
// 对observer remove
NSLog(@"kvoC dealloc");
[_blockArr enumerateObjectsUsingBlock:^(deallocBlock _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj();
}];
}
@end
@interface NSObject ()
/** dict */
@property (nonatomic, strong) NSMutableDictionary <NSString *, kvoBlock> *dict;
/** */
@property (nonatomic, strong) YYKVOController *kvoController;
@end
@implementation NSObject (YYKVO)
- (void)yyObserver:(NSObject *)object keyPath:(NSString *)keyPath block:(kvoBlock)block {
self.dict[keyPath] = block;
self.kvoController.observerdObject = object;
__unsafe_unretained typeof(self)weakSelf = self;
[self.kvoController.blockArr addObject:^{
[object removeObserver:weakSelf forKeyPath:keyPath];
}];
//监听
[object addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
}
// observer里调用
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
// 执行block
kvoBlock block = self.dict[keyPath];
if (block) {
block(change);
}
}
// getter setter
- (NSMutableDictionary<NSString *,kvoBlock> *)dict {
NSMutableDictionary *tempDict = objc_getAssociatedObject(self, @selector(dict));
if (!tempDict) {
tempDict = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, @selector(dict), tempDict, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return tempDict;
}
- (YYKVOController *)kvoController {
YYKVOController *tempKvoController = objc_getAssociatedObject(self, @selector(kvoController));
if (!tempKvoController) {
tempKvoController = [[YYKVOController alloc] init];
objc_setAssociatedObject(self, @selector(kvoController), tempKvoController, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return tempKvoController;
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。