OC学习39.1:runtime初探

张建 lol

Runtime简介

Object_C 是一门动态语言,所以它总是想办法把一些决定工作 从编译器推迟到运行时。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石。

什么是Runtime?

  • 我们都知道,将源代码转换为可执行的程序,通常要经过四个步骤:预处理、编译、汇编、链接。不同的编译语言,在这四个步骤中所进行的操作又有些不同。

  • C/C++静态语言 的代表,它们在 编译阶段 就已经确定好了要调用的函数,以及函数的实现,如果函数未实现就会编译报错。

  • Runtime 又叫 运行时,是一套底层C语言的API,OC就是运行时机制,其中最主要的是 消息机制 。对于OC的函数,属于动态调用过程,在 编译 的时候并不能决定真正调用哪个函数,只有在真正 运行 的时候才会根据函数的名称找到对应的函数来调用。

运行时概念?

运行时:把 函数的调用编译阶段 推迟到 运行时阶段 的能力

多态概念?

多态:不同对象以自己的方式响应相同的消息的能力叫做多态。

消息机制的基本原理

OC的方法调用都是类似 [receiver selector] 的形式,其实每次都是一个运行时消息发送过程。

  1. 编译阶段:[receiver selector]方法被编译器转化:
  • objc_msgSend(receiver,selector)(不带参数)
  • objc_msgSend(recevier,selector,org1,org2,…)(带参数)
  1. 运行时阶段:消息接收者 recever 寻找对应的 selector
  • recever 能找到对应的 selector ,直接执行接收 receiver 对象的 selector 方法。
  • recever 找不到对应的 selector,消息被转发或者临时向recever添加这个selector对应的实现内容,否则崩溃。

消息发送流程总结

调用[receiver selector]后,进行的流程:

  1. 编译阶段:[receiver selector]方法被编译器转化:
  • objc_msgSend(receiver,selector)(不带参数)。
  • objc_msgSend(recevier,selector,org1,org2,…)(带参数)。
  1. 运行时阶段:recevier寻找对应的selector:
  • 通过recevier的isa指针找到recevier的class(类)。
  • 在Class(类)的cache(方法缓存)中寻找对应的selector。
  • 如果在cache(方法缓存)中没有找到对应的 selector ,就继续在Class(类)的methodList(方法列表)中查找,如果找到,缓存到cache 中,并返回selector。
  • 如果在class(类)中没有找到这个selector,就继续在它的superclass(父类)中寻找。
  • 一旦找到selector,直接执行相关联的IMP(方法实现)。
  • 若找不到对应的selector,Runtime系统进入消息转发阶段。
  1. 消息转发阶段:
  • 动态方法解析:通过重写 +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.