一、前言
KVO(Key-value observing)键值编码,是Objective-C对观察者设计模式的又一实现,系统利用了指针混写技术(isa-swizzing)来实现KVO
二、常用的方法说明
// 注册Observer: observer:观察者, keyPath:要观察的属性名称, options:对KVO机制进行配置, context: 传入任意类型的对象
addObserver:forKeyPath:options:context:
// 接收通知: keyPath:被监听的对象的属性,object:被监听的对象,change:被监听的对象的属性值的变化,是一个字典,
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
// 移除观察者
-removeObserver:forKeyPath:
// 自动开关
+ (BOOL) automaticallyNotifiesObserversOfSteps
// 组合监听key值
+ (NSSet<NSString *> *)keyPathsForValuesAffectingValueForKey:(NSString *)key
三、底层原理
- 当一个对象使用了KVO监听,iOS系统会修改这个对象的isa指针,改为指向一个全新的通过Runtime动态创建的子类
NSKVONotifying_xxx
- 然后动态添加
setter
方法 - 动态添加
class
方法 - 动态添加
dealloc
方法 - 开启手动观察,在setter方法前后调用
willChangeValueForKey
和didChangeValueForKey
方法 - 消息转发给原类 newValue
- 消息发送-响应回调方法
四、总结
- 使用
setter
方法改变值KVO才会生效 - 使用
setValue:forKey:
改变值KVO才会生效 - 成员变量直接修改需手动添加KVO才会生效
//直接为成员变量赋值
[self willChangeValueForKey:@"value"];
_value += 1;
[self didChangeValueForKey:@"value"];