美文网首页
iOS 谈谈KVO

iOS 谈谈KVO

作者: Cary9396 | 来源:发表于2018-11-28 16:09 被阅读0次

    今天我们来说一下KVO,KVO通俗得讲就是键值观测,也叫做观察者模式。有时候当我们需要通过一个对象的属性的变化来作出响应时,就会使用KVO。

    KVO两个关键的方法:

    1.添加观察者

     /***************
         @observer:就是观察者,是谁想要观测对象的值的改变。
         @keyPath:就是想要观察的对象属性。
         @options:options一般选择NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld,这样当属性值发生改变时我们可以同时获得旧值和新值,如果我们只填NSKeyValueObservingOptionNew则属性发生改变时只会获得新值。
         @context:想要携带的其他信息,比如一个字符串或者字典什么的。
         **************/
        - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
    

    2.当所观测的属性值发生变化的时候调用:

     /********************
         @keyPath:观察的属性
         @object:观察的是哪个对象的属性
         @change:这是一个字典类型的值,通过键值对显示新的属性值和旧的属性值
         @context:上面添加观察者时携带的信息
         *******************/
        - (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary *)change context:(nullable void *)context;
    
    
    KVO的内部调用顺序

    1.首先调用willChangeValueForKey:方法。
    2.然后调用setAge:方法真正的改变属性的值。
    3.开始调用didChangeValueForKey:这个方法,调用[super didChangeValueForKey:key]时会通知监听者属性值已经改变,然后监听者执行自己的- (void)observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary)change context:(void *)context这个方法。

    KVO的实现原理简要说明

    KVO 是基于 runtime 机制实现的 当某个类的属性对象第一次被观察时,系统就会在运行期动态地创建该类的一 个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。派生类在 被重写的 setter 方法内实现真正的通知机制。

    如果原类为 Person,那么生成的派生类名为 NSKVONotifying_Person 每个类对象中都有一个 isa 指针指向当前类,当一个类对象的第一次被观察,那么 系统会偷偷将 isa 指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的 setter 方法。

    键值观察通知依赖于 NSObject 的两个方法willChangeValueForKey:didChangevlueForKey:;在一个被观察属性发生改变之前, willChangeValueForKey: 一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey: 会被调用,继而observeValueForKey:ofObject:change:context: 也会被调用。

    补充:KVO 的这套实现机制中苹果还偷偷重写了 class 方法,让我们误认为还是使用的当前类,从而达到隐藏生成的派生类。

    直接修改成员变量会触发KVO吗

    不会,KVO的本质是set方法,只有调用了set方法才会触发KVO。

    如何手动触发KVO

    手动调用willChangeValueForKey和didChangeValueForKey方法。

    相关文章

      网友评论

          本文标题:iOS 谈谈KVO

          本文链接:https://www.haomeiwen.com/subject/qptzqqtx.html