IOS-详解KVO底层实现
一、KVO (Key-Value Observing)
KVO 是 Objective-C 对观察者模式(Observer Pattern)的实现。也是 Cocoa Binding 的基础。当被观察对象的某个属性发生更改时,观察者对象会获得通知。
有意思的是,你不需要给被观察的对象添加任何额外代码,就能使用 KVO 。这是怎么做到的?
二、 KVO内部实现原理
- KVO是基于runtime机制实现的
- 当某个类的属性对象
第一次被观察
时,系统就会在运行期动态
地创建该类的一个派生类
,在这个派生类中重写基类中任何被观察属性的setter 方法。派生类在被重写的setter方法内实现真正的通知机制
- 如果原类为Person,那么生成的派生类名为
NSKVONotifying_Person
- 每个类对象中都有一个isa指针指向当前类,当一个类对象的第一次被观察,那么系统会偷偷将isa指针指向动态生成的派生类,从而在给被监控属性赋值时执行的是派生类的setter方法
- 键值观察通知依赖于NSObject 的两个方法:
willChangeValueForKey:
和didChangevlueForKey:
;在一个被观察属性发生改变之前,willChangeValueForKey:
一定会被调用,这就 会记录旧的值。而当改变发生后,didChangeValueForKey:
会被调用,继而observeValueForKey:ofObject:change:context:
也会被调用。 补充:KVO的这套实现机制中苹果还偷偷重写了class方法,让我们误认为还是使用的当前类,从而达到隐藏生成的派生类
三、补充: 如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?(看链接)
四、附注: KVC底层实现原理(如下)
KVC运用了一个isa-swizzling技术. isa-swizzling就是类型混合指针机制, 将2个对象的isa指针互相调换, 就是俗称的黑魔法.
KVC主要通过isa-swizzling, 来实现其内部查找定位的. 默认的实现方法�由NSOject提供isa指针, 如其名称所指,(就是is a kind of的意思), 指向分发表对象的类. 该分发表实际上包含了指向实现类中的方法的指针, 和其它数据。
- 具体主要分为三大步
- 第一步:寻找该属性有没有setsetter方法?有,就直接赋值
- 第二步:寻找有没有该属性带下划线的成员属性?有,就直接赋值
- 第三步:寻找有没有该属性的成员属性?有,就直接赋值
- 或者这么说
- 1、首先搜索setKey:方法.(key指成员变量名, 首字母大写)
- 2、上面的setter方法没找到, 如果类方法accessInstanceVariablesDirectly返回YES. 那么按 _key, _isKey,key, iskey的顺序搜索成员名.(NSKeyValueCodingCatogery中实现的类方法, 默认实现为返回YES)
- 3、如果没有找到成员变量, 调用setValue:forUnderfinedKey:
比如说如下的一行KVC的代码:
举个
IOS-详解KVO底层实现的更多相关文章
- IOS详解TableView——选项抽屉(天猫商品列表)
在之前的有篇文章讲述了利用HeaderView来写类似QQ好友列表的表视图. 这里写的天猫抽屉其实也可以用该方法实现,具体到细节每个人也有所不同.这里采用的是点击cell对cell进行运动处理以展开“ ...
- Block详解二(底层分析)
Block专辑: Block讲解一 MRC-block与ARC-block Block详解一(底层分析) 今天讲述Block的最后一篇,后两篇仅仅是加深1,2篇的理解,废话少说,开始讲解! __blo ...
- Block详解一(底层分析)
本篇博客不再讲述Block的基本定义使用,最近而是看了很多的block博客讲述的太乱太杂,所以抽出时间整理下block的相关底层知识,在讲述之前,提出几个问题,如果都可以回答出来以及知道原理,大神绕过 ...
- iOS:详解MJRefresh刷新加载更多数据的第三方库
原文链接:http://www.ios122.com/2015/08/mjrefresh/ 简介 MJRefresh这个第三方库是李明杰老师的杰作,这个框架帮助我们程序员减轻了超级多的麻烦,节约了开发 ...
- 分布式大牛详解Zookeeper底层原理
很多学员都在反馈,说zk很难学,学的不是很明白,在这里,我继续带着大家详解一遍Zookeeper 首先zk是什么呢首先肯定是一个个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用 ...
- ArrayList详解,底层是数组,实现Serializable接口
一.对于ArrayList需要掌握的七点内容 ArrayList的创建:即构造器往ArrayList中添加对象:即add(E)方法获取ArrayList中的单个对象:即get(int index)方法 ...
- IOS详解TableView——内置刷新,EGO,以及搜索显示控制器
内置刷新 内置刷新是苹果IOS6以后才推出的一个API,主要是针对TableViewController增加了一个属性,refreshControl,所以如果想用这个内置下拉刷新的话,最好给你的Tab ...
- iOS 详解NSXMLParser方法解析XML数据方法
前一篇文章已经介绍了如何通过URL从网络上获取xml数据.下面介绍如何将获取到的数据进行解析. 下面先看看xml的数据格式吧! <?xml version="1.0" enc ...
- IOS详解TableView——对话聊天布局的实现
上篇博客介绍了如何使用UITableView实现类似QQ的好友界面布局.这篇讲述如何利用自定义单元格来实现聊天界面的布局. 借助单元格实现聊天布局难度不大,主要要解决的问题有两个: 1.自己和其他人说 ...
随机推荐
- ES_DEVOPS-1
When dealing with a large number of parallel operations in elasticsearch, such as search requests or ...
- Silverlight中ListBox的数据绑定
在Silverlight中ListBox是一个非常强大的控件.总结下ListBox的绑定数据的方式. 首先,新建一个Book类, public class Book { public string B ...
- 理解本真的REST架构风格(转,解释的最清楚)
add by zhj start: Fielding在批判性继承前人研究成果的基础上,建立起来一整套研究和评价软件架构的方法论.这套方法论的核心是“架构风格”这个概念.架构风格是一种研究和评价软件架构 ...
- mysql参数安全设置
MySQL安全相关的参数有哪些?该如何配置? 1.MySQL数据安全 innodb_flush_log_at_trx_commit =1 #innodb每次提交事务redo buffer 刷新到red ...
- SQL Server查看库、表占用空间大小
转自:https://blog.csdn.net/yenange/article/details/50493580 查询数据文件与日志文件占用情况,查看数据大小,查看库大小 1. 查看数据文件占用(权 ...
- [3D]1.绘制三角形
作为一个.Net程序员学习3D开发好尴尬啊,因为不论是OpenGL还是Direct3D都是用C/C++开发的比较多.虽然有计划使用C++进行开发,但是平时还是C#使用的多.很少用C++做东西,如果仅仅 ...
- Openstack(九)部署nova服务(控制节点)
9.1nova服务介绍 nova是openstack最早的组件之一,nova分为控制节点和计算节点,计算节点通过nova computer进行虚拟机创建,通过libvirt调用kvm创建虚拟机,nov ...
- java map典型排序
List<Map.Entry<TbDiseases, Double>> list = new ArrayList<Map.Entry<TbDiseases,Doub ...
- JDK eclipse selenium的安装以及环境变量的配置
未经允许,禁止转载!!! 未经允许,禁止转载!!! 首先下载安装JDK: 然后双击进行安装 选着第一个:开发工具!点击next 一定要记住:Install to: C:\Program Files\ ...
- django2.0关于path匹配路径页面刷新不出来的问题
下面是官方文档的内容,如果在urls.py中使用到正则匹配路径(^$)的时候,就需要使用re_path,而不能使用path,不然页面会显示404错误, 如果未用到正则,那么使用path即可. re_p ...
- IOS详解TableView——选项抽屉(天猫商品列表)