美文网首页iOS基本功
iOS中的KVC和KVO关系

iOS中的KVC和KVO关系

作者: kyson老师 | 来源:发表于2019-03-22 16:07 被阅读35次

    本系列博客是本人的开发笔记。为了方便讨论,本人新建了一个微信群(iOS技术讨论群),想要加入的,请添加本人微信:zhujinhui207407,【加我前请备注:iOS 】,本人博客http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

    KVC是KVO的技术基础,他们都是利用了OC的动态性。

    概念

    KVC

    NSKeyValueCoding

    A mechanism by which you can access the properties of an object indirectly by name or key.
    译:它是一种可以通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。

    KVO

    全称是Key-value observing,翻译成键值观察。提供了一种当其它对象属性被修改的时候能通知当前对象的机制

    常用方法

    KVC

    所有的方法都在Foundation库的NSKeyValueCoding.h

    ///为对象的属性赋值
    -(void)setValue:(nullable id)value forKey:(NSString *)key;
    // 根据key取值
    - (id)valueForKey:(NSString *)key;  
    // 为对象的属性赋值(包含了setValue:forKey:的功能,并且还可以对对象内的类的属性进行赋值)
     - (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
    // 根据keyPath取值
       - (nullable id)valueForKeyPath:(NSString *)keyPath;
    // 对模型一次性赋值,前提是必须声明好所有对应的属性(key)
    - (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
    

    KVO

    所有的方法都在Foundation库的NSKeyValueObserving.h

    - (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath options:(NSKeyValueObservingOptions)options context:(void *)context;
    - (void)removeObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath;
    

    应用

    CoreData

    修改系统控件的内部属性(Runtime+KVC)

    其他

    KVO与Notification(通知)的区别?

    notification 比 KVO 多了发送通知的一步。
    两者都是一对多,但是对象之间直接的交互,notification 明显得多,需要notificationCenter 来做为中间交互。而 KVO 如我们介绍的,设置观察者->处理属性变化,至于中间通知这一环,则隐秘多了,只留一句“交由系统通知”,具体的可参照以上实现过程的剖析。
    notification 的优点是监听不局限于属性的变化,还可以对多种多样的状态变化进行监听,监听范围广,例如键盘、前后台等系统通知的使用也更显灵活方便。

    实现原理

    KVC

    当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。
    派生类在被重写的 setter 方法实现真正的通知机制,就如前面手动实现键值观察那样。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制。当然前提是要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现 KVO 的。
    同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。此外,派生类还重写了 dealloc 方法来释放资源。

    KVO

    当某个类的对象第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的 setter 方法。

    派生类在被重写的 setter 方法实现真正的通知机制,就如前面手动实现键值观察那样。这么做是基于设置属性会调用 setter 方法,而通过重写就获得了 KVO 需要的通知机制。当然前提是要通过遵循 KVO 的属性设置方式来变更属性值,如果仅是直接修改属性对应的成员变量,是无法实现 KVO 的。
    同时派生类还重写了 class 方法以“欺骗”外部调用者它就是起初的那个类。然后系统将这个对象的 isa 指针指向这个新诞生的派生类,因此这个对象就成为该派生类的对象了,因而在该对象上对 setter 的调用就会调用重写的 setter,从而激活键值通知机制。此外,派生类还重写了 dealloc 方法来释放资源。

    参考

    [深入浅出Cocoa]详解键值观察(KVO)及其实现机理

    KVC/KVO原理详解及编程指南

    如何自己动手实现 KVO

    Introduction to Key-Value Observing Programming Guide

    iOS开发 -- KVO的实现原理与具体应用

    相关文章

      网友评论

        本文标题:iOS中的KVC和KVO关系

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