KVC/KVO实现原理分析

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1. 函数调用(消息)实现分析:

我们看这条语句:

[代码]c#/cpp/oc代码:

1 [self.person setValue:@"Vincent"forKey:@"name"];

就会被编译器处理成:

[代码]c#/cpp/oc代码:

1 SEL sel = sel_get_uid ("setValue:forKey:");
2  
3 IMP method = objc_msg_lookup (self.person->isa,sel);
4  
5 method(self.person, sel,@"Vincent",@"name");

也就是说iOS中函数调用并不是被静态编译为地址调用,而是被转为查表、调用!

2. 这里需要介绍几个基本概念:

(1). SEL数据类型:它是编译器运行Objective-C里的方法的环境参数。

(2). IMP数据类型:他其实就是一个 编译器内部实现时候的函数指针。当Objective-C编译器去处理实现一个方法的时候,就会指向一个IMP对象,这个对象是C语言表述的类型(事实上,在Objective-C的编译器处理的时候,基本上都是C语言的)。

(3). isa指针,如其名称所指,(就是is a kind of的意思),指向维护分发表的对象的类。该分发表实际上包含了指向实现类中的方法的指针,和其它数据。


3.  KVO/KVC实现分析:

当我们为一个类的某个属性添加observer时候,框架自动创建这个类的一个子类,并且修改这个类的isa指向这个新的子类。

由于在ios中函数调用都是转化为isa查表形式,所以这次查得时新的子类的表,

也就是说对类的函数调用被子类给拦截了,在拦截的实现中就可以通知observer了。


修改类的isa被称为isa-swizzling技术。isa-swizzling就是类型混合指针机制。KVC主要通过isa-swizzling,来实现其内部查找定位的。


比如还是这段代码:   

[代码]c#/cpp/oc代码:

1 [self.person setValue:@"Vincent"forKey:@"name"];


它会被编译为:

[代码]c#/cpp/oc代码:

1 SEL sel = sel_get_uid ("setValue:forKey:");
2  
3 IMP method = objc_msg_lookup (self.person->isa,sel);
4  
5 method(self.person, sel,@"Vincent",@"name");


这里的isa是动态生成的子类,你debugger调试一个被观察的类就会发现它的isa已经发生了变化!而没有被观察的类的isa是正常的,如图所示:

06173946_Etu4.png

也就是说我们调用setValue...的时候实际上已经调用observer的didChangeValueForKey:方法!


因为KVC的实现机制,可以很容易看到某个KVC操作的Key,而后也很容易的跟观察者注册表中的Key进行匹对。假如访问的Key是被观察的Key,那么我们在内部就可以很容易的到观察者注册表中去找到观察者对象,而后给他发送消息。


转载于:https://my.oschina.net/u/1782374/blog/376211

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/545294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小白学算法:买卖股票的最佳时机!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)本文已收录至 Github《小白学算法》系列:https://github.com/vipstone/algorith今天蚂蚁集团(支付宝…

《APUE》第6章笔记

这一章主要介绍了口令文件和组文件的结构和一些围绕这些结构的函数。 口令文件即passwd就是在/etc/passwd中可以查阅。其结构是: 上图四个平台能支持的就用黑点表示。 因为加密口令这一项放在passwd这个人人可读的文件中,可能会有安全问题。所以现在的Li…

聊聊近期的感受和10月文章精选!

先来看本月的原创文章汇总,其中算法部分也有少量 9 月份的文章,这样汇总起来大家看起来更方便,目录如下。算法系列小白学算法第1篇:一文详解「栈」和手撸栈的两种方法!小白学算法第2篇:JDK 竟然是这样实现栈…

第六章关系数据理论

第六章关系数据理论6.1_问题的提出(略)6.2_规范化6.2.1_函数依赖6.2.2_码6.2.3_范式6.2.4_2NF6.2.5_3NF6.2.6_BCNF6.2.7_多值依赖6.2.8_4NF6.2.9_规范化小结6.3_Armstrong公理系统6.3.1_函数依赖闭包6.3.2_最小依赖集6.3.3_转换为3NF的保持函数依赖的分解…

Github上的热门iOS开源项目:AFNetworking、MagicalRecord、BlocksKit以及XVim

1. AFNetworking AFNetworking是一个非常受欢迎的轻量级的iOS、Mac OS X网络通信类库。它建立在NSURLConnection、NSOperation以及其技术的基础上,有着精心设计的模块结构和功能丰富的API,让很多网络通信功能的实现变得十分简单。 附件:/c…

队列实现栈的3种方法,全都击败了100%的用户!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)本文已收录至 Github《小白学算法》系列:https://github.com/vipstone/algorith之前我们讲过《用两个栈实现一个…

where、having、group by、order by、count的使用注意

where、having、group by、order by、count的使用注意1_where、having、group by、order by的顺序2_group by的作用3_where和group by的组合4_group by和having的组合5_where、having、group by的组合使用6_count与group by的组合使用1_where、having、group by、order by的顺序…

很实用的21个SQL小技巧!

前言每一个好习惯都是一笔财富,本文基于MySQL,分SQL后悔药, SQL性能优化,SQL规范优雅三个方向,分享写SQL的21个好习惯,谢谢阅读,加油哈~1. 写完SQL先explain查看执行计划(SQL性能优化…

阿里最喜欢问的多线程顺序打印的5种解法!

Keeper导读大家在换工作面试中,除了一些常规算法题,还会遇到各种需要手写的题目,所以打算总结出来,给大家个参考。全文 2929 字,剩下的是代码,P6 及以下阅读只需要 8 分钟,高 P 请直接关闭第一篇…

CSS入门

CSS入门1_CSS概要1.1_CSS引入方式2_CSS选择器3_字体样式3.1_字体属性3.2_字体类型:font-family3.3_字体大小:font-size3.4_字体粗细:font-weight3.5_字体颜色:color3.6_总结4_文本样式4.1_文本样式属性4.2_首行缩进:te…

23张图!万字详解「链表」,从小白到大佬!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)链表和数组是数据类型中两个重要又常用的基础数据类型。数组是连续存储在内存中的数据结构,因此它的优势是可以通…

何为“秒传”

写在前面 最近一直在弄文件传输的组件,在讨论组里面,有同事提到“秒传”的功能。在目前的通信软件中也有网盘的功能,就从网上搜了一下,这里对“秒传”的实现思路做一下总结,在之后会写一个小的demo实现一下。没有其他&…

数组转List的3种方法和使用对比!

作者 | 大脑补丁来源 | blog.csdn.net/x541211190/article/details/79597236前言:本文介绍Java中数组转为List三种情况的优劣对比,以及应用场景的对比,以及程序员常犯的类型转换错误原因解析。一.最常见方式(未必最佳)…

oracle10g备份导入

2019独角兽企业重金招聘Python工程师标准>>> //导出 exp test/testgdsoft filed:\gd.dmp //删用户 drop user wkwx cascade; //用PLSQL创建数据数据库 create user hzjzjn identified by hzjzjn default tablespace BDP_DATABD; grant CREATE USER,DROP USER,ALTE…

VisualSVNServer的使用

VisualSVNServer的使用1_服务端初识1.1_创建新仓库1.2_创建用户并分配权限1_服务端初识 1.1_创建新仓库 右击Repository,点击create 点击下一步 输入仓库名 右击空白处,点击新建,点击project structure 输入工程名 1.2_创建用户并分…

安利一个IDEA骚操作:一键生成方法的序列图

在平时的学习/工作中,我们会经常面临如下场景:阅读别人的代码阅读框架源码阅读自己很久之前写的代码。千万不要觉得工作就是单纯写代码,实际工作中,你会发现你的大部分时间实际都花在了阅读和理解已有代码上。为了能够更快更清晰地…

c#中textbox属性_C#.Net中带有示例的TextBox.Multiline属性

c#中textbox属性Here we are demonstrating use of Multiline property of the TextBox Control. 在这里,我们演示了TextBox控件的Multiline属性的使用。 Multiline property contains two values: 多行属性包含两个值: True: We can enter text in mo…

MATLAB新手教程

MATLAB新手教程 1.MATLAB的基本知识 1-1、基本运算与函数 在MATLAB下进行基本数学运算,仅仅需将运算式直接打入提示号(>>)之後,并按入Enter键就可以。比如: >> (5*21.3-0.8)*10/25 an…

嗯,查询滑动窗口最大值的这4种方法不错....

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)本文已收录至 Github《小白学算法》系列:https://github.com/vipstone/algorithm这是一道比较基础的算法题&…

SVN客户端使用

SVN客户端使用1. 复制服务端URL2. 在客户端电脑新建文件夹用于存储版本代码3. 右击空白处,checkout4. 进入trunk目录,即可尝试新建文件并上传到服务端4.其他客户端更新版本5.解决代码冲突期间由于之前登陆过并设置为记住密码,所以整个过程并没…