首页 > 代码库 > KVC,KVO 实现原理

KVC,KVO 实现原理

Key-Value Coding: 键值编码 (KVC)

方法调用: 

// 对象属性 
// 类似: Person -> name
setValue: forKey:// 对象的属性或者 属性的属性...... 可见它已经包含前者.
// 类似: Person -> car -> name
setValue: forKeyPath:

KVC运用了一个isa-swizzling技术。isa-swizzling就是类型混合指针机制, 将2个对象的isa指针互相调换, 就是俗称的黑魔法。

KVC主要通过isa-swizzling,来实现其内部查找定位的。默认的实现方法由NSOject提供

  isa指针,如其名称所指,(就是is a kind of的意思),指向分发表对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。

比如说如下的一行KVC的代码:

[object setValue:@"134567" forKey:@"uid"];就会被编译器处理成:// 首先找到对应selSEL sel = sel_get_uid("setValue:forKey:");// 根据object->isa找到sel对应的IMP实现指针IMP method = objc_msg_lookup (object->isa,sel);// 调用指针完成KVC赋值method(object, sel, @"134567", @"uid");

KVC如何访问属性值

KVC再某种程度上提供了访问器的替代方案。不过访问器方法是一个很好的东西,以至于只要是有可能,KVC也尽量再访问器方法的帮助下工作。为了设置或者返回对象属性,KVC按顺序使用如下技术:
①检查是否存在-<key>、-is<key>(只针对布尔值有效)或者-get<key>的访问器方法,如果有可能,就是用这些方法返回值;
检查是否存在名为-set<key>:的方法,并使用它做设置值。对于-get<key>和-set<key>:方法,将大写Key字符串的第一个字母,并与Cocoa的方法命名保持一致;
②如果上述方法不可用,则检查名为-_<key>、-_is<key>(只针对布尔值有效)、-_get<key>和-_set<key>:方法;
③如果没有找到访问器方法,可以尝试直接访问实例变量。实例变量可以是名为:<key>或_<key>;
④如果仍为找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey:方法。这些方法的默认实现都是抛出异常,我们可以根据需要重写它们

 

KVC,KVO 实现原理