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.自己和其他人说 ...
随机推荐
- Oracle管理监控之Oracle数据库存储空间监控
1.监控表空间使用率 基表:dba_data_files.dba_free_space 脚本: select a.tablespace_name, round((a.maxbytes / 1024 / ...
- 设计模式之——Composite模式
composite模式又叫做组合模式/复合模式. 它是一种能够使容器与内容具有一致性,创造出递归结构的模式. 示例程序是列出文件夹以及其内部文件与文件夹一览的功能: 可以由示例图看出,有一个电影文件夹 ...
- html锚点的作用和js选项卡锚点跳转的使用
location是javascript里边管理地址栏的内置对象,比如location.href就管理页面的url,用location.href=url就可以直接将页面重定向url.而location. ...
- 当Web访问性能出现问题,如何深探?
对运维或开发工程师来说,遇到访问性能问题时,最先需要定位的是问题出现在哪个环节,是网络的问题,服务端的问题,还是客户端的问题? 往往技术人员喜欢把精力放在保障后端服务的可用性方面,而对前端界面是否能正 ...
- Git版本控制工具安装与配置
这里太多,我写在这里方便复制: sudo yum -y install zlib-devel openssl-devel cpio expat-devel gettext-devel curl-dev ...
- 数据挖掘---支持向量机(SVM)
•1.SVM 的基本思想: •SVM把分类问题转换成寻求分类平面的问题,并通过最大化分类边界点到分类平面的距离来实现分类.通俗的讲支持向量机的解决的问题是找到最好的分类超平面.支持向量机(Suppor ...
- Winform开发之ComboBox和ComboBoxEdit控件绑定key/value数据
使用 ComboBox 控件绑定key/value值: 因为 ComboBox 是有 DataSource 属性的,所以它可以直接绑定数据源,如 DataTable.ListItem 等. 使用 Da ...
- Java实现使用位图生成真值组合
摘要: 使用位图生成真值组合. 难度: 初级. /** * 问题描述: 给定 n 个布尔变量,打印所有真值组合. * 例如, n = 2 时 , 所有真值组合为 (true, false),(tr ...
- 向Oracle 数据表中插入一条带有日期类型的数据
有一张表:batch(批次表) 表的字段如下: 第一种情况: 现在需要插入一条当前的系统时间 sql 如下: insert into batch (batch_id, cus_id, batch_nu ...
- 将flex页面嵌入到jsp页面中
如果我们只需要用到Flex的一部分功能,例如播放器功能,我们可以单独把Flex页面嵌入到Jsp页面中.要想实现此功能,需要下载一个工程,将其覆盖在服务器根目录下即可.你可以在次下载:FlexModul ...
- IOS详解TableView——选项抽屉(天猫商品列表)