探究KVC本质

细致的看了下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;

赋值原理图:

image.png

二、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有两个方法:willChangeForKeydidChangeForKey,因为 KVC 内部调用了这两个方法,所以直接赋值成员变量的时候也可以触发KVO

所以KVC 赋值的时候,无论有没有set方法,都可以触发KVO

end,谢谢!

你可能感兴趣的:(探究KVC本质)