iOS runtime(理论篇)

一.从objc_msgSend开始说

[receiver message] 
//会被编译器转化为
objc_msgSend(receiver, selector) 

所以当我们调用一个方法时,会执行的过程大致如下: 1.rutime系统会把方法调用转化为消息发送,并且把方法的调用者,和方法选择器,当做参数传递过去。 2.方法的调用者会通过isa 指针来找到所属的类,然后在 cache 或者 methodLists 中查找该方法,找得到就跳到对应的方法去执行。 3.如果在类中没找到该方法,则通过super_class 往上一级超类查找。如果一直找到 NSObject 都没有找到该方法的话,可能就会触发到消息转发。

二. runtime 的术语的数据结构

上面讲的是执行过程里面有一些术语接下来大概介绍下。

1.SEL

selector 是方法选择器,其实作用就和名字一样,日常生活中,我们通过人名辨别谁是谁。 Objective-C在编译的时候,会根据方法的名字,生成一个用 来区分这个方法的唯一的一个ID,这个ID就是SEL类型的。我们需要注意的是,只要方法的名字相同,那么它们的ID都是相同的。就是说,不管是超类还是子类,不管是有没有超类和子类的关系,只要名字相同那么ID就是一样的。

    -(void)setWidth:(int)width;   
    -(void)setWidth:(double)width;   

这样的函数则被认为是一种编译错误,而这最终导致了一个非常非常奇怪的Objective-C特色的函数命名:

    -(void)setWidthIntValue:(int)width;   
    -(void)setWidthDoubleValue:(double)width;   

本质上,SEL只是一个指向方法的指针,它的存在只是为了加快方法的查询速度。

2.Class

Class 其实是指向 objc_class 结构体的指针

3.Method

Method 代表类中某个方法的类型

4.Ivar

Ivar 是表示成员变量的类型。

5.IMP

它就是一个函数指针,这是由编译器生成的。当你发起一个 ObjC 消息之后,最终它会执行的那段代码,就是由这个函数指针指定的。而 IMP 这个函数指针就指向了这个方法的实现。 如果得到了执行某个实例某个方法的入口,我们就可以绕开消息传递阶段,直接执行方法,这在后面 Cache 中会提到。 你会发现 IMP 指向的方法与 objc_msgSend 函数类型相同,参数都包含 id 和 SEL 类型。每个方法名都对应一个 SEL 类型的方法选择器,而每个实例对象中的 SEL 对应的方法实现肯定是唯一的,通过一组 id和 SEL 参数就能确定唯一的方法实现地址。 而一个确定的方法也只有唯一的一组 id 和 SEL 参数。

6.Cache

Cache 为方法调用的性能进行优化,每当实例对象接收到一个消息时,它不会直接在 isa 指针指向的类的方法列表中遍历查找能够响应的方法,因为每次都要查找效率太低了,而是优先在 Cache 中查找。 Runtime 系统会把被调用的方法存到 Cache 中,如果一个方法被调用,那么它有可能今后还会被调用,下次查找的时候就会效率更高。就像计算机组成原理中 CPU 绕过主存先访问 Cache 一样。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏佳爷的后花媛

java学习要点

作为一个程序员,在找工作的过程中,都会遇到笔试,而很多笔试里面都包括java,尤其是作为一个Android开发工程师,java是必备技能之一.所以为了笔试过程中...

2335
来自专栏飞雪无情的博客

从Java到Golang快速入门

Golang从09年发布,中间经历了多个版本的演进,已经渐渐趋于成熟,并且出现了很多优秀的开源项目,比如我们熟知的docker,etcd,kubernetes等...

893
来自专栏代码世界

Python之面向对象四

面向对象进阶 一、关于面向对象的两个内置函数 isinstance   判断类与对象的关系    isinstance(obj,cls)检查obj是否是类 cl...

37313
来自专栏me的随笔

Python知识梳理

我们可以使用type()函数类获取对象的类型,Python3中内置数据类型包括:None,int,float,complex,str,list,dict,tup...

1192
来自专栏绿巨人专栏

TypeScript中的怪语法

3805
来自专栏Python中文社区

Python源码剖析之整数对象

專 欄 ❈ 松直,Python中文社区专栏作者 专栏地址: http://www.zhihu.com/people/songzhili?utm_source...

2348
来自专栏Fundebug

如何禁止JavaScript对象重写?

译者按: 使用Object.preventExtensions()、Object.seal()和Object.freeze(),可以禁止重写JavaScript...

1375
来自专栏博岩Java大讲堂

关于Java泛型"擦除"的一点思考

2835
来自专栏Ryan Miao

java基础面试题

参考:http://blog.csdn.net/jackfrued/article/details/44921941 说未经允许不转载,我只好参考了。 1.面向...

3615
来自专栏我是攻城师

Apache Pig学习笔记之内置函数(三)

4054

扫码关注云+社区