KVC set和get方法的赋值查找流程
1.KVC 是什么?
KVC全称是Key Value Coding,定义在NSKeyValueCoding.h文件中, 是键值编码,是对象间接访问其属性的一种机制
2.set方法如何查找赋值
2.1 基本数据类型的赋值顺序
setValue:forKey:
方法的默认实现
1 调用方法
按照
set<Key>
和_set<Key>
的顺序查找方法,找到之后直接调用方法并完成操作
2 设置实例变量
没有找到方法,则如果类方法
accessInstanceVariablesDirectly
的返回值为YES
,那么将按
_<key>
、_is<Key>
、<key>
、is<Key>
的顺序依次寻找相关实例变量,找到设置对应变量并完成操作
3 调用未定义方法
前两步都没有设值成功,会调用
setValue:forUndefinedKey
方法,默认情况下如果未实现该方法将会引发异常
2.2 可变数组的赋值顺序
mutableArrayValueForKey: 的默认实现,给定
key
做输入参数,返回一个可变数组,对这个数组做添加删除操作,可响应外接的KVO监听事件
1 查找可变数组方法
查找一对方法
insertObject:in<key>AtIndex:
和removeObjectFrom<Key>AtIndex:
或者insert<Key>:atIndexs:
和remove<Key>AtIndexs:
这个两个方法对应可变数组的insertObjcet:atIndex:
和removeObjectAtIndex:
或者insertObjects:atIndexs:
和removeObjectsAtIndexs:
如果找到至少一个
insert
方法和一个remove
方法,就返回一个代理对象,用来响应NSMutableArray的插入删除消息。当接收
mutableArrayValueForKey:
的消息对象还实现了可选的替换方法,名称为replaceObjectIn<Key>AtIndex:withObject:
或replace<Key>AtIndexes:with<Key>
,代理对象也将在适当的情况下利用它们来获得最佳性能
2 查找set方法
如果没有可变数组方法,则查找一个格式为
set<Key>:
的替代方法。
这种情况下,通过向set<Key>:
发送消息,来返回一个代理对象响应可变数组事件。
提示:这一步不如上一步有效,可能重复创建集合对象。
3 查找实例变量
没有找到可变数组方法,也没有找到set方法,如果类方法
accessInstanceVariablesDirectly
的返回值为YES
则查找实例变量
顺序为_<key>
、<key>
,如果找到实例变量,
则返回一个代理对象
4 调用未定义方法
如果上边都没有找到,就返回一个可变集合代理对象,当触发可变数组方法时,就向元素对象发出
valueForUndefinedKey:
和setValue:forUndefinedKey:
方法,并会引发一个NSUndefinedKeyException的异常
2.3 可变有序集合的赋值
mutableOrderedSetValueForKey:
的默认实现,同可变数组
2.4 可变集合的赋值
mutableSetValueForKey:
的默认实现
1 查找可变方法
搜索名称为
add<Key>Object:
和remove<Key>Object:
或者add<Key>:
和remove<Key>:
的方法
对应NSMutableSet
的
addObject:
和removeObject:
或者unionSet:
和minusSet:
如果发现至少一个添加方法和至少一种去除方法,返回的代理对象用来响应集合的方法。
代理对象还使用名称类似
intersect<Key>:
或set<Key>:
来对应原始对象中的方法。
其他方法同可变数组
3.get方法如何查找
1 查找简单方法
按顺序
get<Key>
,<key>
,is<Key>
或者_<key>
查找方法,找到之后调用并执行第5步
2 查找数组方法
搜索方法名为
countOf<Key>
和objectIn<Key>AtIndex:
和<key>AtIndexes:
如果找到count
方法并找到后两个方法的至少一个,则创建一个响应NSArray的方法的代理对象并返回
代理对象将NSArray的方法调用上面的方法给原始对象.
3 查找集合方法
搜索方法中是否有
countOf<Key>
、enumeratorOf<Key>
、memberOf<Key>:
如果找到三个方法,就创建一个响应NSSet方法的代理对象并返回
4 查找实例变量
如果接收类的
accessInstanceVariablesDirectly
返回YES
按顺序_<key>
,_is<Key>
,<key>
,或者is<Key>
查找实例变量,如果找到,直接获取变量的值返回
5 转换对象类型
如果找到的属性值是对象指针,则直接返回
如果找到的属性值是NSNumber类型,则将其存储到NSNumber实例中并返回
如果找到的属性是NSNumber不支持的类型,转换为NSValue对象并返回
6 如果其他方法均失败,则调用 valueForUndefinedKey:
,默认情况下会引发异常。