AI智能
改变未来

iOS面试 – runtime & 消息转发机制


runtime

1. 什么是runtime?

  • runtime 运行时机制,是一套比较底层的纯 C 语言 API , 属于1个 C 语言库, 包含了很多底层的 C 语言 API 。(引入 <objc/runtime.h> 或者 <objc/message.h> )
  • 程序运行过程时,我们平时编写的 OC 代码, 其实最终都是转成了 runtime 的 C 语言代码。
  • 在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才能根据函数的名称找到对应的函数来调用。

2. runtime 是干什么用的?使用场景是什么?

  • runtime 是属于 OC 的底层, 可以进行一些非常底层的操作;
  • 使用场景1:动态创建一个类 ( 比如 KVO 的底层实现 ) objc_allocateClassPair、class_addIvar、objc_registerClassPair; 例如:热创建。
  • 使用场景2:动态地为某个类添加属性/方法, 修改属性值/方法(修改封装的框架) objc_setAssociatedObject、object_setIvar; 例如:热更新。
  • 使用场景3:遍历一个类的所有成员变量(属性)/所有方法(字典转模型,归解档) class_copyIvarList、class_copyPropertyList、class_copyMethodList;例如:YYmodel、MJextension、JsonModel。
  • 使用场景4:查找对象,实现万能跳转;例如:收到推送的通知跳转到对应的页面。

消息转发机制

1. 消息转发机制的原理

  • 当向一个对象发送消息时,objc_msgSend 方法根据对象的 isa 指针找到对象的类,然后在类的调度表(dispatch table)中查找 selector。
  • 如果无法找到 selector,objc_msgSend 通过指向父类的指针找到父类,并在父类的调度表(dispatch table)中查找 selector,以此类推直到 NSObject 类。
  • 一旦查找到 selector,objc_msgSend 方法根据调度表的内存地址调用该实现。
  • 通过这种方式,message 与方法的真正实现才在执行阶段进行绑定。
  • 为了保证消息发送与执行的效率,系统会将全部 selector 和使用过的方法的内存地址缓存起来。
  • 每个类都有一个独立的缓存,缓存包含有当前类自己的 selector 以及继承自父类的 selector。
  • 查找调度表(dispatch table)前,消息发送系统首先检查 receiver 对象的缓存;缓存命中的情况下,消息发送(messaging)比直接调用方法(function call)只慢一点点。

2. 消息转发中各个参数分别代表什么?

  • sel: 一种类型,表示方法名称,类似字符串(可互转)。
  • isa: 在方法底层对应的 objc_msgSend 调用时会根据 isa 找到对象所在的类对象,类对象中包含了调度表(dispatch table),该表将类的 sel 和方法的实际内存地址关联起来。
  • super_class: 每一个类中还包含了一个 super_class 指针,用来指向父类对象。
  • _cmd: 在Objective-C 的方法中表示当前方法的 selector,正如同 self 表示当前方法调用的对象实例。
  • IMP: 定义为 id (*IMP) (id, SEL, …)。这样说来, IMP 是一个指向函数的指针,这个被指向的函数包括 id (\”self\”指针),调用的 SEL(方法名),再加上一些其他参数。说白了 IMP 就是实现方法。

3. 动态绑定

  • 在运行时确定要调用的方法,动态绑定将调用方法的确定也推迟到运行时。
  • 在编译时,方法的调用并不和代码绑定在一起,只有在消实发送出来之后,才确定被调用的代码。
  • 通过动态类型和动态绑定技术,您的代码每次执行都可以得到不同的结果。
  • 运行时因子负责确定消息的接收者和被调用的方法;运行时的消息分发机制为动态绑定提供支持。
  • 当您向一个动态类型确定了的对象发送消息时,运行环境系统会通过接收者的 isa 指针定位对象的类,并以此为起点确定被调用的方法,方法和消息是动态绑定的。而且,您不必在 Objective-C 代码中做任何工作,就可以自动获取动态绑定的好处。
  • 您在每次发送消息时,特别是当消息的接收者是动态类型已经确定的对象时,动态绑定就会例行而透明地发生
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » iOS面试 – runtime & 消息转发机制