KVC,KVO 实现原理
Posted Taurin_Coder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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"]; 就会被编译器处理成: // 首先找到对应sel SEL 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 实现原理的主要内容,如果未能解决你的问题,请参考以下文章
ios开发runtime学习五:KVC以及KVO,利用runtime实现字典转模型
NotificationCenter KVC KVO Delegate总结