在日常的开发中,KVC是我们经常使用来给对象赋值和取值的,通常会使用- (void)setValue:(nullable id)value forKey:(NSString *)key;赋值,使用- (nullable id)valueForKey:(NSString *)key;取值,相信使用方法大家都已经非常熟悉了,那么它的底层原理是什么呢?这次就来研究一下。不过由于我们并不能直接看到源码,所以需要借助官方文档来研究。
KVC的赋值原理
官方文档解释如下:
- 1、首先会调用
setter方法,具体顺序为:set<Key> -> _set<Key> -> setIs<Key>,如果找到了则把相应的value赋值给对应的属性。 - 2、判断
+ (BOOL)accessInstanceVariablesDirectly的结果:- 如果返回值为
YES,则会去查找成员变量,具体顺序为:_<key> -> _is<Key> -> <key> -> is<Key>,如果找到了则把相应的value赋值给对应成员变量。 - 如果返回值为
NO,则跳转到第三步。
- 如果返回值为
- 3、调用
setValue:forUndefinedKey:方法报错。
KVC的取值原理
官方解释如下:
- 1、首先以
get<key> -> <key> -> is<Key> -> _<key>的顺序查找对象中的对应方法,如果找到了则将返回值携带上跳到第五步,如果没找到则跳到第二步。 - 2、查找是否有
countOf<Key>和objectIn<Key>AtIndex:方法以及<key>AtIndexes:方法,如果找到了第一个方法并且再找到了其他两个方法中的至少一个,则创建一个响应所有NSArray方法的集合代理对象并返回。没有找到则跳到第三步。 - 3、查找是否有
countOf<Key>、enumeratorOf<Key>和memberOf<Key>这三个方法,如果这三个方法都被找到则创建一个响应所有NSSet方法的集合代理对象。没有找到则跳到第四步。 - 4、判断方法
+ (BOOL)accessInstanceVariablesDirectly的返回值:- 如果返回值为
YES,则以_<key> -> _is<Key> -> <key> -> is<Key>的顺序查找成员变量,如果找到了则携带上对应成员变量的值跳转到第五步。 - 如果返回值为
NO,则跳转到第六步。
- 如果返回值为
- 5、判断属性值:
- 如果取出的属性值是指针对象,则直接返回结果。
- 如果该值是
NSNumber支持的变量类型,则将其存储在一个NSNumber的实例中并返回。 - 如果该值不是
NSNumber支持的变量类型,则将其转换成一个NSValue类型的对象并返回。
- 6、调用
valueForUndefinedKey:方法报错。
以上就是KVC赋值和取值的底层原理了,主要是通过查看官方文档来了解,也说明了官方文档是很重要的,有问题还是应该及时去官方文档查看。