細致的看了下KVC的東西,記錄一下。
KVC:key-value-coding,鍵值編碼。
KVC可以干什么?
利用KVC可以給類的屬性、成員變量賦值。
常用方法:
- (void)setValue:(nullable id)value forKey:(NSString *)key;
- (void)setValue:(nullable id)value forKeyPath:(NSString *)keyPath;
- (nullable id)valueForKey:(NSString *)key;
- (nullable id)valueForKeyPath:(NSString *)keyPath;
具體KVC 的用法,就不說了。
一、setValue:forKey
原理
1.先去找setKey
,然后再去找_setKey
;
2.如果1不滿足,那么會調用+ (BOOL)accessInstanceVariablesDirectly
(是否允許轉發給成員變量,默認返回YES)。如果返回NO,那么執行方法:- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
程序Crash。如果返回YES執行3;
3.查找順序如下:_key
,_isKey
,key
,isKey
,找到賦值,如果找不到執行- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;
程序Crash;
賦值原理圖:
二、valueForKey:
原理
1.按順序查找:getKey
,key
,isKey
,_key
2.如果1不滿足,那么會調用+ (BOOL)accessInstanceVariablesDirectly
(是否允許轉發給成員變量,默認返回YES)。如果返回NO,那么執行方法:- valueForUndefinedKey:
程序Crash。如果返回YES執行3
3.查找順序如下:_key
,_isKey
,key
,isKey
,找到賦值,如果找不到執行valueForUndefinedKey:
程序Crash
賦值原理圖:
三、KVC 與 KVO
1.KVC 賦值屬性時,是否會觸發KVO?
答案是肯定的,可以觸發KVO。(觸發KVO 的一個重要條件是,屬性具有set
方法);
2.如果我們直接賦值成員變量,會不會觸發KVO?
答案也是肯定的,可以觸發KVO。為什么?之前記錄KVO的時候主動觸發KVO有兩個方法:willChangeForKey
和 didChangeForKey
,因為 KVC 內部調用了這兩個方法,所以直接賦值成員變量的時候也可以觸發KVO
所以KVC 賦值的時候,無論有沒有set方法,都可以觸發KVO
end,謝謝!