KVC set和get方法的赋值查找流程


官方文档地址

1.KVC 是什么?

KVC全称是Key Value Coding,定义在NSKeyValueCoding.h文件中, 是键值编码,是对象间接访问其属性的一种机制

2.set方法如何查找赋值

2.1 基本数据类型的赋值顺序

setValue:forKey: 方法的默认实现

1 调用方法

按照 set_set 的顺序查找方法,找到之后直接调用方法并完成操作

2 设置实例变量

没有找到方法,则如果类方法accessInstanceVariablesDirectly 的返回值为 YES,那么将按
__isis的顺序依次寻找相关实例变量,找到设置对应变量并完成操作

3 调用未定义方法

前两步都没有设值成功,会调用 setValue:forUndefinedKey方法,默认情况下如果未实现该方法将会引发异常

2.2 可变数组的赋值顺序

mutableArrayValueForKey: 的默认实现,给定key做输入参数,返回一个可变数组,对这个数组做添加删除操作,可响应外接的KVO监听事件

1 查找可变数组方法

查找一对方法 insertObject:inAtIndex:removeObjectFromAtIndex:或者 insert:atIndexs:removeAtIndexs:
这个两个方法对应可变数组的 insertObjcet:atIndex:removeObjectAtIndex:或者insertObjects:atIndexs:removeObjectsAtIndexs:

如果找到至少一个insert方法和一个remove方法,就返回一个代理对象,用来响应NSMutableArray的插入删除消息。

当接收mutableArrayValueForKey:的消息对象还实现了可选的替换方法,名称为replaceObjectInAtIndex:withObject:replaceAtIndexes:with,代理对象也将在适当的情况下利用它们来获得最佳性能

2 查找set方法

如果没有可变数组方法,则查找一个格式为set:的替代方法。
这种情况下,通过向set:发送消息,来返回一个代理对象响应可变数组事件。

提示:这一步不如上一步有效,可能重复创建集合对象。

3 查找实例变量

没有找到可变数组方法,也没有找到set方法,如果类方法accessInstanceVariablesDirectly 的返回值为 YES 则查找实例变量
顺序为 _,如果找到实例变量,
则返回一个代理对象

4 调用未定义方法

如果上边都没有找到,就返回一个可变集合代理对象,当触发可变数组方法时,就向元素对象发出valueForUndefinedKey:setValue:forUndefinedKey:方法,并会引发一个NSUndefinedKeyException的异常

2.3 可变有序集合的赋值

mutableOrderedSetValueForKey: 的默认实现,同可变数组

2.4 可变集合的赋值

mutableSetValueForKey:的默认实现

1 查找可变方法

搜索名称为
addObject:removeObject: 或者 add:remove: 的方法
对应 NSMutableSet
addObject:removeObject:或者 unionSet:minusSet:

如果发现至少一个添加方法和至少一种去除方法,返回的代理对象用来响应集合的方法。

代理对象还使用名称类似intersect:set:来对应原始对象中的方法。

其他方法同可变数组

3.get方法如何查找

1 查找简单方法

按顺序 get,,is或者_ 查找方法,找到之后调用并执行第5步

2 查找数组方法

搜索方法名为 countOfobjectInAtIndex:AtIndexes:
如果找到count方法并找到后两个方法的至少一个,则创建一个响应NSArray的方法的代理对象并返回

代理对象将NSArray的方法调用上面的方法给原始对象.

3 查找集合方法

搜索方法中是否有 countOfenumeratorOfmemberOf:
如果找到三个方法,就创建一个响应NSSet方法的代理对象并返回

4 查找实例变量

如果接收类的 accessInstanceVariablesDirectly返回YES
按顺序 __is,或者is查找实例变量,如果找到,直接获取变量的值返回

5 转换对象类型

如果找到的属性值是对象指针,则直接返回
如果找到的属性值是NSNumber类型,则将其存储到NSNumber实例中并返回
如果找到的属性是NSNumber不支持的类型,转换为NSValue对象并返回

6 如果其他方法均失败,则调用 valueForUndefinedKey:,默认情况下会引发异常。

iOS