KVC进阶知识

KVC是如何通过key来存取属性的?这里是有一套规则的:

valueForKey:的查找规则

  1. 查找是否存在比较直接的访问方法。按照get, , is, _的顺序,如果找到就调用该方法并带着结果到步骤5,否则到第2步继续查找。
  2. 查找是否存在类似数组的方法。首先查找是否存在countOf方法,再查找是否有objectInAtIndex:或AtIndexes: 其中一个方法,如果找到,则会返回一个代理对象,该对象类似一个数组,数组含有的元素个数为第一个方法返回值,数组内的元素就是第二个方法返回值。在这种情况下不管属性是否是数组,kvc的返回值都是数组,实际类为NSKeyValueArray。
    如果未找到上述方法,到第3步继续查找。
  3. 查找是否存在类似NSSet的方法。查找是否有countOf, enumeratorOf, 和 memberOf:三个方法,如果有则返回一个代理对象 ,该对象类似一个NSSet,和第2步类似。
    如果未找到上述3个方法,到第4步继续查找。
  4. 直接查找实例变量。按照_, _is, , is的顺序,如果找到则直接获取变量并到步骤5,否则到步骤6。
  5. 如果得到的值是一个对象,直接返回结果。
    如果得到一个可转为NSNumber非对象值,转为NSNumber并返回。
    如果得到一个不可转为NSNumber的非对象值,如结构体,转为NSValue并返回。
  6. 未找到,调用valueForUndefinedKey:方法。

setValue:forKey:的查找规则

  1. 查找是否存在比较直接的访问方法。按照set:,_set的顺序,如果找到则调用该方法。否则到步骤2继续查找。
  2. 直接查找实例变量。按照_, _is, , is的顺序,如果找到直接设置变量。否则到步骤3。
  3. 未找到,调用setValue:forUndefinedKey:方法。

mutableArrayValueForKey:的查找规则

总是返回一个可变代理数组,遵循如下规则

  1. 查找insertObject:inAtIndex: removeObjectFromAtIndex:,insert:atIndexes: 和 removeAtIndexes:这些方法。如果找到至少一个插入方法和至少一个删除方法,则返回一个代理对象,该对象对于可变数组的插入和删除的响应会转至上述方法。
  2. 没有找到上述可变数组的类似方法,则查找set:方法,返回一个代理对象,该对象对可变数组的插入和删除操作都会调用该方法。
  3. 前2步都未找到,直接查找实例变量,按照_的顺序,返回一个代理对象,该对象对可变数组的方法都会直接转发至实例变量,该变量最好是一个可变数组类,否则可能出现异常。
  4. 上述都未找到,依然返回一个可变代理数组,其接收到的可变数组的操作都会调用setValue:forUndefinedKey:方法。
    值得注意的是,在满足上述步骤1或步骤2后,返回值会遵循valueForKey:的查找规则。

mutableOrderedSetValueForKey:和mutableSetValueForKey:查找规则

与mutableArrayValueForKey:类似,有兴趣的可查看官方文档或API说明

你可能感兴趣的:(KVC进阶知识)