48_iOS干货31_KVO的使用,底层原理,优缺点,应用场合

一,KVO的使用步骤

  1. 对象添加监听器,监听某个属性
  2. 改变对象的属性
  3. 调用系统监听方法
  4. 监听完毕,消除监听器
 // 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函数,并执行

  1. willChangeValueForKey:
  2. 父类原来的setter
  3. didChangeValueForKey:
  4. 内部会触发监听器(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即可

猜你喜欢

转载自blog.csdn.net/a_horse/article/details/82634192