為什么說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.