KVC/KVO的实现原理简述
2016-03-25 20:57
232 查看
一、KVC
KVC全称为key-value coding,键值编码。就是提供了一种机制可以访问一个对象的任意属性。它是通过使用字符串作为关键字而不是使用setter/getter访问器去访问一个对象实例的属性的机制。1.1 实现原理:
(问题:KVC是如何访问属性的)(1)如果是取值操作,检查是否存在-,-is,或者-get的对应key的访问器方法,如果有则调用这些方法。
如果是设值操作,检查是否存在-set方法,并使用它来进行属性设值。对于get和set岂会遵循Cocoa方法命名规范,把key首字符大写,所以我们平时也要注意属性和方法的命名规范!
(2)如上如方法不可用,则检查是否存在对应的 -_,-_is,-_get和-_set方法。
(3)如果没有找到访问器方法,则尝试直接访问成员变量。其名一般为或_。
(4)如果仍未找到,则调用valueForUndefinedKey:和setValue:forUndefinedKey方法。这两个方法默认会抛出异常,我们也可以重写这些方法进行对应情况的处理。
二、KVO
KVO全程为key-value observing,键值观察。提供了一种当指定的对象的属性发生变化时,则通知所有的观察者的机制。通常用于model和controller之间。2.1 实现原理:
(1)KVC和KVO都和一种叫isa-swizzling的技术有关,其依赖于runtime机制提供的强大动态能力。(2)当某个类的实例第一次被观察时,系统会在运行期间动态的创建一个该类的派生类,在这个派生类会重写父类中被观察属性的setter方法。
派生类中被重写的setter方法实现了真正的通知机制。这么做的原因是根据KVC的实现机制,我们会发现其修改属性的实质就是通过调用属性的访问器进行的。所以如果遵循KVO的属性设置方式来修改属性值,就可以实现对属性修改的观察;否则的话,如果直接修改属性对应的成员变量值,是无法实现KVO的。
(3)同时该派生类还重写了class方法,以“欺骗”外部调用者,让它们还以为它还是原来的那个类。然后系统将这个对象的isa指针指向这个派生类的Class实例,其实际是这个实例早以成为派生类的对象了。所以使用者调用属性的访问器修改属性时实际上是调用了派生类中重写的setter方法,从而激活了键值通知的机制。此外,派生类也重写了dealloc方法来释放资源。
2.1 重点
派生类会在setter方法中增加两个方法的调用。- (void)willChangeValueForKey:(NSString *)key - (void)didChangeValueForKey:(NSString *)key
其中,会在didChangeValueForKey:里调用观察者的这个方法。
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
以上就是KVO的实现原理了!
为了唤醒键值观察(KVO),也可以手动调用will/didChangeValueForKey。
参考资料
KVC/KVO原理详解及编程指南相关文章推荐
- Python动态类型的学习---引用的理解
- 土人系列AS入门教程 -- 对象篇
- C#托管堆对象实例包含内容分析
- C#实现获取不同对象中名称相同属性的方法
- javascript asp教程第十一课--Application 对象
- ASP编码必备的8条原则
- PowerShell中使用Out-String命令把对象转换成字符串输出的例子
- VBS教程:对象-正则表达式(RegExp)对象
- C#检查指定对象是否存在于ArrayList集合中的方法
- XML指南——XML编码
- C#中字符串编码处理
- ExtJS中文乱码之GBK格式编码解决方案及代码
- sql2008启动代理未将对象应用到实例解决方案
- 程序员趣味读物 谈谈Unicode编码
- 文本文件编码方式区别
- C#编程自学之类和对象
- C++中对象的常引用、动态建立和释放相关知识讲解
- C语言安全编码之数值中的sizeof操作符
- C#实现获取文本文件的编码的一个类(区分GB2312和UTF8)
- VC中BASE64编码和解码使用详解