iOS中的KVC和KVO关系

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 *)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关系)