ios

为什么说KVO是基于KVC实现的

2018-08-16  本文已影响50人  lkkwxy

为什么说KVO是基于KVC实现的

在阅读本篇文章之前,需要你了解KVC和KVO的基本实现,如不清楚,可先阅读下面两篇文档KVC的基本使用KVO的基本使用

在学习KVO的时候,看很多文章都说KVO是基于KVC实现的

KVO实现原理(只针对普通对象,不包括集合)

  1. 当某个类的属性被观察时,系统会在运行时动态的创建一个该类的子类。并且把改对象的isa指向这个子类

  2. 假设被观察的属性名是name,若父类里有setName:或这_setName:,那么在子类里重写这2个方法,若2个方法同时存在,则只会重写setName:一个(这里和KVCset时的搜索顺序是一样的)

  3. 若被观察的类型是NSString,那么重写的方法的实现会指向_NSSetObjectValueAndNotify这个函数,这个函数里会调用willChangeValueForKey:didChangevlueForKey:,并且会在这2个方法调用之间,调用父类set方法的实现

  4. 系统会在willChangeValueForKey:对observe里的change[old]赋值,取值是用valueForKey:取值的,didChangevlueForKey:对observe里的change[new]赋值,然后调用observe的这个方法- (void)observeValueForKeyPath:(nullable NSString *)keyPath ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change context:(nullable void *)context;

  5. 当使用KVC赋值的时候,在NSObject里的setValue:forKey:方法里,若父类不存在setName:或这_setName:这些方法,会调用_NSSetValueAndNotifyForKeyInIvar这个函数,这个函数里同样也会调用willChangeValueForKey:didChangevlueForKey:,若存在则调用

为什么说KVO基于KVC实现的

  1. 当使用KVO观察某个类属性时,会为该类创建一个子类,子类重写setter方法时,跟KVCset时的搜索顺序是一样的,都是先搜索set<Key>,然后在搜_set<Key>。对于KVC,若不存在会有后续操作,参考上面的文档

  2. 在为observe的change字典里的old和new赋值时,用到了KVC的valueForKey:

  3. 也许是苹果在KVO文档里的这句话。为了理解KVO,你首先要理解KVC

Important: In order to understand key-value observing, you must first understand key-value coding.

参考

  1. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueCoding/BasicPrinciples.html
  2. https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html
上一篇下一篇

猜你喜欢

热点阅读