iOS开发 — KVC原理探索

787 阅读3分钟

在日常的开发中,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赋值和取值的底层原理了,主要是通过查看官方文档来了解,也说明了官方文档是很重要的,有问题还是应该及时去官方文档查看。