一、Runtime 概念
Runtime是一套底层纯C语言API,OC代码最终都会被编译器转化为运行时代码,通过消息机制决定函数调用方式。
runtime简称运行时。OC是运行时机制,也就是在运行时才做一些处理。其中最主要的是消息机制(函数调用),属于动态调用过程。在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。
每一个oc的方法,底层必然有一个与之对应的runtime方法。
二、理解消息机制的基本原理
OC的方法调用都是类似[receiver selector]的形式,其实每次都是一个运行时消息发送过程。
第一步:编译阶段
[receiver selector]方法被编译器转化,分为两种情况:
1.不带参数的方法被编译为:objc_msgSend(receiver,selector)
2.带参数的方法被编译为:objc_msgSend(recevier,selector,org1,org2,…)
第二步:运行时阶段
消息接收者recever寻找对应的selector,也分为两种情况:
1.接收者能找到对应的selector,直接执行接收receiver对象的selector方法。
2.接收者找不到对应的selector,消息被转发或者临时向接收者添加这个selector对应的实现内容,否则崩溃。
说明:OC调用方法[receiver selector],编译阶段确定了要向哪个接收者发送message消息,但是接收者如何响应决定于运行时的判断。
三、与Runtime的交互
Runtime的官方文档中将OC与Runtime的交互划分三种层次:OC源代码,NSObject方法,Runtime 函数。这其实也是按照与Runtime交互程度从低到高排序的三种方式。
1.OC源代码(Objec-C Source Code)
我们已经说过,OC代码会在编译阶段被编译器转化。OC中的类、方法和协议等在Runtime中都由一些数据结构来定义。所以,我们平时直接使用OC编写代码,其实这已经是在和Runtime进行交互了,只不过这个过程对于我们来说是无感的。
2.NSObject方法(NSObject Methods)
Runtime的最大特征就是实现了OC语言的动态特性。作为大部分Objective-C类继承体系的根类的NSObject,其本身就具有了一些非常具有运行时动态特性的方法,比如respondsToSelector:方法可以检查在代码运行阶段当前对象是否能响应指定的消息,所以使用这些方法也算是一种与Runtme的交互方式,类似的方法还有如下:
image.png
3.使用Runtime函数(Runtime Functions)
Runtime系统是一个由一系列函数和数据结构组成,具有公共接口的动态共享库。头文件存放于/usr/include/objc目录下。在我们工程代码里引用Runtime的头文件,同样能够实现类似OC代码的效果,一些代码示例如下:
image.png
四、Runtime 应用
1、消息传递
2、动态变量控制
3、动态添加方法
4、动态交换两个方法的实现
5、拦截并替换方法
6、在方法上增加额外功能
7、实现NSCoding的自动归档和解档
8、实现字典转模型的自动转换
五:实践
参考文章:
https://cloud.tencent.com/developer/article/1158131
https://www.jianshu.com/p/fe131f8757ba
https://www.jianshu.com/p/46dd81402f63
OC的消息机制可以分为一下三个阶段:
1、消息发送阶段:从类及父类的方法缓存列表及方法列表查找方法;
2、动态解析阶段:如果消息发送阶段没有找到方法,则会进入动态解析 阶段,负责动态的添加方法实现;
3、消息转发阶段:如果也没有实现动态解析方法,则会进行消息转发阶 段,将消息转发给可以处理消息的接受者来处理;










网友评论