1、KVO是什么
KVO(Key-Value Observing),俗称键值监听,用于监听某个对象属性的改变
2、KVO的使用
调用KVO的监听方法:
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
并且实现KVO方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
}
3、实现原理
根据demo,我们自定义的类KVOObject
,包含一个count
属性,当我们监听self.objc
对象属性的时候,发现self.objc->isa
指向的是一个全新的类:NSKVONotifying_KVOObject
当我们监听对象属性的时候,实际上是通过监听对象的setter方法,当我们使用KVO监听之前,
self.objc
对象的isa
指针指向的是KVOObject
对象,增加KVO监听之后,runtime会动态地将我们的self.objc
指向一个新创建的临时类NSKVONotifying_KVOObject
,当我们监听对象某个属性的时候,实际上是重新setter方法,伪代码实现为:
- (void)setCount:(NSInteger)count {
[self willChangeValueForKey:@"count"];
[super setCount:count];
[self didChangeValueForKey:@"count"];
}
- (void)didChangeValueForKey:(NSString *)key {
[observe observeValueForKeyPath:key ofObject:self change:change context:context];
}
结论:KVO实现原理
利用RuntimeAPI动态生成一个子类,并且让instance
对象的isa
指向这个全新的子类
当修改instance
对象的属性时,会调用Foundation
的_NSSetXXXValueAndNotify
函数,然后执行:
1、willChangeValueForKey:
2、父类原来的setter
3、didChangeValueForKey:
,其内部会触发监听器(Oberser
)的监听方法( observeValueForKeyPath:ofObject:change:context:
)
网友评论