首页 > 代码库 > KVC的底层实现原理

KVC的底层实现原理

KVC是OC特有的,本质是在运行时动态的给对象发送setValue:forKey 消息,设置数值 -调用super.init 保证对象已经被创建完成 .当给对象发送setValue:forKey 消息时要判断对象是否存在key所对应的属性,直接赋值 如果没有就调用undefinedKey(默认崩溃,需要重写)    

 setValue:forKey的调用顺序首先会寻找set<key>方法,如果没有就去找_<key>  _is<Key>  <key> is<key> 顺序寻找,如何还没找到就调用undefinedKey(默认崩溃,需要重写).

 ValueForKey的调用顺序   按照get<key>, <key> is<key> 顺序寻找,如果没有找到按照_<key> _is<key>  <key> is<key>顺序寻找,如何还没找到就调用undefinedKey(默认崩溃,需要重写).
 
 

a. setValue:forKey的搜索方式:

1. 首先搜索set<Key>:方法

如果成员用@property,@synthsize处理,因为@synthsize告诉编译器自动生成set<Key>:格式的setter方法,所以这种情况下会直接搜索到。

注意:这里的<Key>是指成员名,而且首字母大写。下同。

2. 上面的setter方法没有找到,如果类方法accessInstanceVariablesDirectly返回YES(注:这是NSKeyValueCodingCatogery中实现的类方法,默认实现为返回YES)。

那么按_<key>,_is<Key>,<key>,is<key>的顺序搜索成员名。

 
3. 如果找到设置成员的值,如果没有调用setValue:forUndefinedKey:。
 

b. valueForKey:的搜索方式:

1. 首先按get<Key>、<key>、is<Key>的顺序查找getter方法,找到直接调用。如果是bool、int等内建值类型,会做NSNumber的转换。

2. 上面的getter没有找到,查找countOf<Key>、objectIn<Key>AtIndex:、<Key>AtIndexes格式的方法。

如果countOf<Key>和另外两个方法中的一个找到,那么就会返回一个可以响应NSArray所有方法的代理集合(collection proxy object)。发送给这个代理集合(collection proxy object)的NSArray消息方法,就会以countOf<Key>、objectIn<Key>AtIndex:、<Key>AtIndexes这几个方法组合的形式调用。还有一个可选的get<Key>:range:方法。

3. 还没查到,那么查找countOf<Key>、enumeratorOf<Key>、memberOf<Key>:格式的方法。

如果这三个方法都找到,那么就返回一个可以响应NSSet所有方法的代理集合(collection proxy object)。发送给这个代理集合(collection proxy object)的NSSet消息方法,就会以countOf<Key>、enumeratorOf<Key>、memberOf<Key>:组合的形式调用。

4. 还是没查到,那么如果类方法accessInstanceVariablesDirectly返回YES,那么按_<key>,_is<Key>,<key>,is<key>的顺序直接搜索成员名。

 
5. 再没查到,调用valueForUndefinedKey:。 

KVC的底层实现原理