一,KVO的使用步骤
- 对象添加监听器,监听某个属性
- 改变对象的属性
- 调用系统监听方法
- 监听完毕,消除监听器
// 1,给person1对象添加KVO监听
//监听选项:一般选择旧值和新值;
//context参数会传给到监听方法
NSKeyValueObservingOptions options = NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld;
[self.person1 addObserver:self forKeyPath:@"age" options:options context:@"123"];
// 2,改变对象的属性值
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
self.person1.age = 20;
}
// 3,当监听对象的属性值发生改变时,就会调用监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
//旧值的获取change[NSKeyValueChangeOldKey];
//新值的获取change[NSKeyValueChangeNewKey]
NSLog(@"监听到%@的%@属性值改变了 - %@ - %@", object, keyPath, change, context);
}
//4,移除监听器
- (void)dealloc {
[self.person1 removeObserver:self forKeyPath:@"age"];
}
二,KVO的底层实现
1,利用RuntimeAPI动态生成一个子类,并且让instance对象的isa指向这个全新的子类
2,当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数,并执行
- willChangeValueForKey:
- 父类原来的setter
- didChangeValueForKey:
- 内部会触发监听器(Oberser)的监听方法( observeValueForKeyPath:ofObject:change:context:)
3,除了重新属性的set方法,还有重新classs方法,以“欺骗”外部调用者它就是起初的那个类
三,KVO的优缺点
优点:代码实现简单;mode和view的同步;没有观察者时0开销
缺点:在创建子类、重写方法等等方面的内存消耗很巨大
四,KVO的使用场合
1.实现上下拉刷新控件 content offset
2.webview混合排版 content size
3.监听模型属性实时更新UI
4,等等
五,问题:直接修改成员变量(不同于属性,没有setter方法)是否会触发KVO?
1,不会,因为KVO本质是替换属性的setter方法;
2,如果要手动触发,在修改成员值前后,要多调用willChangeValueForKey,,和didChangeValueForKey即可