OC学习39.1:runtime初探
Runtime简介
Object_C
是一门动态语言,所以它总是想办法把一些决定工作 从编译器推迟到运行时
。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石。
什么是Runtime?
我们都知道,将源代码转换为可执行的程序,通常要经过四个步骤:
预处理、编译、汇编、链接
。不同的编译语言,在这四个步骤中所进行的操作又有些不同。C/C++
是静态语言
的代表,它们在编译阶段
就已经确定好了要调用的函数,以及函数的实现,如果函数未实现就会编译报错。Runtime
又叫运行时
,是一套底层C语言的API,OC就是运行时机制,其中最主要的是消息机制
。对于OC的函数,属于动态调用过程,在编译
的时候并不能决定真正调用哪个函数,只有在真正运行
的时候才会根据函数的名称找到对应的函数来调用。
运行时概念?
运行时:把 函数的调用
从 编译阶段
推迟到 运行时阶段
的能力
多态概念?
多态:不同对象以自己的方式响应相同的消息的能力叫做多态。
消息机制的基本原理
OC的方法调用都是类似 [receiver selector]
的形式,其实每次都是一个运行时消息发送过程。
- 编译阶段:[receiver selector]方法被编译器转化:
- objc_msgSend(receiver,selector)(不带参数)
- objc_msgSend(recevier,selector,org1,org2,…)(带参数)
- 运行时阶段:消息接收者
recever
寻找对应的selector
:
recever
能找到对应的selector
,直接执行接收receiver
对象的selector
方法。recever
找不到对应的selector
,消息被转发或者临时向recever添加这个selector对应的实现内容,否则崩溃。
消息发送流程总结
调用[receiver selector]后,进行的流程:
- 编译阶段:[receiver selector]方法被编译器转化:
- objc_msgSend(receiver,selector)(不带参数)。
- objc_msgSend(recevier,selector,org1,org2,…)(带参数)。
- 运行时阶段:recevier寻找对应的selector:
- 通过recevier的isa指针找到recevier的class(类)。
- 在Class(类)的cache(方法缓存)中寻找对应的selector。
- 如果在cache(方法缓存)中没有找到对应的 selector ,就继续在Class(类)的methodList(方法列表)中查找,如果找到,缓存到cache 中,并返回selector。
- 如果在class(类)中没有找到这个selector,就继续在它的superclass(父类)中寻找。
- 一旦找到selector,直接执行相关联的IMP(方法实现)。
- 若找不到对应的selector,Runtime系统进入消息转发阶段。
- 消息转发阶段:
动态方法解析:通过重写
+resolveInstanceMethod:
或者+resolveClassMethod:
方法,利用class_addMethod
方法添加其他函数实现。快速转发阶段:如果上一步没有添加其他函数实现,可在当前对象中利用
forwardingTargetForSelector:
方法将消息的接受者转发给其他对象。慢速转发阶段:如果上一步返回值为nil,则利用
methodSignatureForSelector:
方法获取函数的参数和返回值类型。如果
methodSignatureForSelector:
返回nil
。则Runtime
系统会发出doesNotRecognizeSelector:
消息,程序也就崩溃了。如果
methodSignatureForSelector:
返回了一个函数签名
,Runtime就会创建一个NSInvocation
对象并发送-forwardInvocation:
消息给目标对象。
- Post title:OC学习39.1:runtime初探
- Post author:张建
- Create time:2020-08-11 23:25:14
- Post link:https://redefine.ohevan.com/2020/08/11/OC/OC学习39.1:Runtime初探/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.