为什么说KVO是基于KVC实现的
在阅读本篇文章之前,需要你了解KVC和KVO的基本实现,如不清楚,可先阅读下面两篇文档KVC的基本使用和KVO的基本使用
在学习KVO的时候,看很多文章都说KVO是基于KVC实现的
KVO实现原理(只针对普通对象,不包括集合)
-
当某个类的属性被观察时,系统会在运行时动态的创建一个该类的子类。并且把改对象的isa指向这个子类
-
假设被观察的属性名是
name
,若父类里有setName:
或这_setName:
,那么在子类里重写这2个方法,若2个方法同时存在,则只会重写setName:
一个(这里和KVCset时的搜索顺序是一样的) -
若被观察的类型是NSString,那么重写的方法的实现会指向
_NSSetObjectValueAndNotify
这个函数,这个函数里会调用willChangeValueForKey:
和didChangevlueForKey:
,并且会在这2个方法调用之间,调用父类set方法的实现 -
系统会在
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;
-
当使用KVC赋值的时候,在NSObject里的
setValue:forKey:
方法里,若父类不存在setName:
或这_setName:
这些方法,会调用_NSSetValueAndNotifyForKeyInIvar
这个函数,这个函数里同样也会调用willChangeValueForKey:
和didChangevlueForKey:
,若存在则调用
为什么说KVO基于KVC实现的
-
当使用KVO观察某个类属性时,会为该类创建一个子类,子类重写setter方法时,跟KVCset时的搜索顺序是一样的,都是先搜索set<Key>,然后在搜_set<Key>。对于KVC,若不存在会有后续操作,参考上面的文档
-
在为
observe
的change字典里的old和new赋值时,用到了KVC的valueForKey:
-
也许是苹果在KVO文档里的这句话。为了理解KVO,你首先要理解KVC
Important: In order to understand key-value observing, you must first understand key-value coding.
网友评论