美文网首页
KVO底层实现原理

KVO底层实现原理

作者: 是超超呀 | 来源:发表于2021-04-27 16:17 被阅读0次

    KVO的本质

    key-value observer,键值监听,对某一个实例对象进行该实例对象某一个属性值的监听addObserver:forKeyPath:options:content:对象添加监听的方法

    参数

    observer,需要谁(实例对象)来监听

    keyPath,需要监听的属性名称 不是所有的属性都可以监听

    options,监听该属性的方式 新值 / 旧值

    content,携带值,一般为nil

    KVO 不会对self进行强引用,如果观察者的生命周期结束了,self被释放,所以添加的监听需要被移除。

    iOS用什么方式实现对一个对象的KVO?(KVO的本质是什么?)

    利用RuntimeAPI动态生成一个子类NSKVONotifying,并且让instance对象的isa指向这个全新的子类,当修改instance对象的属性时,会调用Foundation的_NSSetXXXValueAndNotify函数willChangeValueForKey:

    父类原来的setter

    didChangeValueForKey:

    内部会触发监听器(Oberser)的监听方法(observeValueForKeyPath:ofObject:change:context:)

    如何手动触发KVO?

    手动调用willChangeValueForKey:和didChangeValueForKey:

    KVO

    kvo

    未使用KVO监听的对象

    实例对象的isa指针指向类对象,因为类对象在内存中存储的信息有isa指针,superclass,属性,对象方法,协议,成员变量等,因此可以在类对象中找到对象方法,进行调用。
    使用了KVO监听的对象

    当一个实例对象调用添加监听属性的方法时,实际上是runtime动态创建了一个名为“NSKVONotifying_Person类名”的类,该类会继承与person类,并且让该实例对象的isa指针重新指向了这个动态创建的类的类对象。因此在该实例对象属性修改值的时候,实际上在内存中该实例对象通过isa指针找到了动态创建的这个子类的类对象,这个动态的类对象中重写了属性的set方法,只是这个动态类的set方法实现并不是直接修改该属性的值,而是调用了一个名叫 “_NSSetIntValueAndNotify的C方法。

    _NSSetIntValueAndNotify方法的内部实现,相当于在调用原来的set方法实现之前,加入 willChangeValueForKey,在其方法后,加入didChangeValueForKey,以此来记录属性的新值和旧值。然后在重写didChangeValueForKey方法中,通过调用 observer的observerValueForKeyPath:ofObject:change:content方法通知监听者。

    NSSetxxxValueAndNotify内部实现

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

    不会 因为没有调用set方法,KVO的本质就是重写set方法

    相关文章

      网友评论

          本文标题:KVO底层实现原理

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