KVO 的实现原理

  1. KVO是关于runtime机制实现的

  2. 当某个类的对象属性第一次被观察时,系统就会在运行期动态地创建该类的一个派生类,在这个派生类中重写基类中任何被观察属性的setter方法。派生类在被重写的setter方法内实现真正的通知机制

  3. 如果原类为Person,那么生成的派生类名为NSKVONotifying_Person

  4. 每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统就会偷偷讲isa指针指向动态生成的派生类,从而在给被监控属性复制是执行的是派生类的setter方法

  5. 键值观察通知依赖于NSObject的两个方法:willChangeValueForKey:和didChangeValueForKey:,在一个被观察属性发生改变之前,willChangeValueForkey:和didChangeValueForKey:;在一个被观察属性发生改变之前,willChangeValueForKey:一定会被调用,这就会记录旧的值。而当改变发生后,didChangeValueForKey:会被调用,继而observeValueForKey:ofObject:change:context:也会被调用

举例伪代码_NSSet*ValueAndNotify

- (void)setAge:(int)age
{_NSSetIntValueAndNotify();
}// 伪代码
void _NSSetIntValueAndNotify()
{[self willChangeValueForKey:@"age"];[super setAge:age];[self didChangeValueForKey:@"age"];
}- (void)didChangeValueForKey:(NSString *)key
{// 通知监听器,某某属性值发生了改变[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}

KVC的实现原理

  • KVC是Key Value Coding的简称。它是一种可以通过字符串的名字(key)来访问类属性的机制。而不是通过调用Setter、Getter方法访问。KVC的方法定义在Foundation/NSKeyValueCoding中。

KVC使用的基本方法:

- (void)setValue:(nullableid)value forKey:(NSString*)key;//通过Key来设值
- (void)setValue:(nullableid)value forKeyPath:(NSString*)keyPath;//通过KeyPath来设值
- (nullableid)valueForKey:(NSString*)key;//直接通过Key来取值
- (nullableid)valueForKeyPath:(NSString*)keyPath;//通过KeyPath来取值

KVC 赋值 setValue:forKey:

  1. setValue:forKey:将键字符串key所对应的属性的值设置为value。(按照setKey:、_setKey:顺序查找方法)如果没有找到Set方法的话,将调用方法setValue:ForUndefinedKey:。并抛出异常 NSUnknowKeyException

2. 若没有找到Set方法,会调用对象的类方法+ (BOOL)accessInstanceVariablesDirectly;此方法返回YES时(默认返回YES),会按照_key,_iskey,key,iskey的顺序搜索成员,然后赋值。

3.  若都没找到成员变量,将调用方法setValue:ForUndefinedKey:。并抛出异常 NSUnknowKeyException

KVC 取值值 valueForKey:

  1. 按先后顺序搜索getKey:、key、isKey、三个方法,若某一个方法被实现,取到的即是方法返回的值,后面的方法不再运行。如果是BOOL或者Int等值类型, 会将其包装成一个NSNumber对象。

  2. 若这三个方法都没有找到,则会调用+ (BOOL)accessInstanceVariablesDirectly方法判断是否允许取成员变量的值。若返回NO,直接调用- (nullable id)valueForUndefinedKey:(NSString *)key方法,并抛出异常 NSUnknowKeyException

  3. 若返回YES,会按先后顺序取_key、_isKey、 key、isKey成员变量的值。调用- (nullable id)valueForUndefinedKey:(NSString *)key方法。

补充

  1. KVC提供属性值正确性验证的API,它可以用来检查set的值是否正确、为不正确的值做一个替换值或者拒绝设置新值并返回错误原因。
- - (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
  1. KVC中的异常.获取值时找不到key- (nullable id)valueForUndefinedKey:(NSString *)key;

  2. 设值时找不到key- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;

  3. 给不能设置nil的属性设置了nil。
  • 如果你在SetValue方法时面给Value传nil,则会调用这个方法
  • (void)setNilValueForKey:(NSString *)key;

转载于:https://www.cnblogs.com/ShaoYinling/p/10238492.html

KVC/KVO 本质相关推荐

  1. zzz KVC/KVO原理详解及编程指南

    前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的理解. 2.由于KVO内容较少,而且是以KVC为基础实现的,本文将着重介绍KVC部分. 一.简介 KVC/KVO是观察者模 ...

  2. KVC/KVO原理详解及编程指南

    作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注 ...

  3. KVC\KVO 简介

    KVC\KVO 简介 一.定义: 二.常见方法代码 KVC: KVC进阶用法: KVO: KVO 进阶用法: 三.用处 KVC: KVO: 四.MVVM.MVVMM架构 一.定义: KVC 是OC一个 ...

  4. 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态

    一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...

  5. KVC/KVO 使用细节和调用顺序

    Key-Value Coding (KVC) Key-Value Coding (KVC) KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象 ...

  6. MJiOS底层笔记--KVO本质

    本文属笔记性质,主要针对自己理解不太透彻的地方进行记录. 推荐系统直接学习小码哥iOS底层原理班---MJ老师的课确实不错,强推一波. NSKVONotifying_Person KVO时,将被监听的 ...

  7. Ios KVC KVO

    一.KVC与KVO *"KVC":key value Coding(键值编码) *目的:间接的修改或获取对象的属性,降低程序(类与类)之间的耦合度. *"KVO" ...

  8. 深入理解 KVC\KVO 实现机制 — KVC

    KVC和KVO都属于键值编程而且底层实现机制都是isa-swizzing,所以本来想放在一起讲的.但是篇幅有限所以就分成了两篇博文 KVO实现机制传送门 KVC概述 KVC是Key Value Cod ...

  9. KVC/KVO实现原理分析

    2019独角兽企业重金招聘Python工程师标准>>> 1. 函数调用(消息)实现分析: 我们看这条语句: [代码]c#/cpp/oc代码: 1 [self.person setVa ...

最新文章

  1. java图形用户界面添加背景颜色不成功的解决方案
  2. 我的数字万用表怎么了?
  3. linux shell pushd popd dirs命令
  4. sock使用UDP协议进行广播发送数据
  5. MongoDB中的GridFs是什么
  6. Object有哪些公用方法?
  7. 中国体外冲击波碎石机市场趋势报告、技术动态创新及市场预测
  8. 【COCOS2D-HTML5 开发之三】演示样例项目附源代码及执行的GIF效果图
  9. 监控易:智慧高校一体化综合运维解决方案
  10. vbs整人代码蓝屏_vbs整人程序大全
  11. 基于python的计算基因组_【ROSALIND】【练Python,学生信】05 计算DNA序列GC含量
  12. CCF优秀博士学位论文奖初评名单出炉!清华入选4人,数量第一
  13. 为什么博客图片不显示?
  14. 考研二战日记-第34天——高数6.2可分离变量的微分方程
  15. 2020年最全最好用的在线文档盘点,建议收藏
  16. 8.PPP拨号 获取ip地址
  17. 初中生也能看懂的狭义相对论(1.世界是什么?)(原子,质子和分子)(看不懂算我输)
  18. vue-cli3的项目 CDN链接报错解决 Uncaught TypeError: Cannot read property 'prototype' of undefined at Object.
  19. web前端在手机上查看电脑上的项目(电脑请求的数据手机可以同步,可以热更新)
  20. Wex5 开发工具及相关插件安装

热门文章

  1. 对于C++中多态的理解
  2. oracle linux查看磁盘,fdisk命令_Linux fdisk命令使用详解:查看磁盘使用情况与磁盘分区...
  3. 深度学习之循环神经网络(2)循环神经网络原理
  4. wps两列数据分别作为xy轴_0.4 秒,完成两列数据核对
  5. 『ACM-算法-二分法』信息竞赛进阶指南--二分法
  6. 数组输出黑科技----fwrite()
  7. 数学--数论--最小公倍数+最大公约数
  8. 消息摘要的编程使用(MD5、SHA、HMAC)
  9. python采用pika库使用rabbitmq总结,多篇笔记和示例
  10. 解决 Gedit 中文乱码