细致的看了下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
赋值原理图:
image.png
三、KVC 与 KVO
1.KVC 赋值属性时,是否会触发KVO?
答案是肯定的,可以触发KVO。(触发KVO 的一个重要条件是,属性具有set
方法);
2.如果我们直接赋值成员变量,会不会触发KVO?
答案也是肯定的,可以触发KVO。为什么?之前记录KVO的时候主动触发KVO有两个方法:willChangeForKey
和 didChangeForKey
,因为 KVC 内部调用了这两个方法,所以直接赋值成员变量的时候也可以触发KVO
所以KVC 赋值的时候,无论有没有set方法,都可以触发KVO
end,谢谢!
网友评论