美文网首页
Runtime(消息转发机制)

Runtime(消息转发机制)

作者: 迷失的信徒 | 来源:发表于2021-03-12 16:32 被阅读0次

1、什么是Runtime

Runtime->运行时机制,最主要的是消息机制,是一套比较底层的纯C语言API,属于一个C语言库,包含了很多了很多底层的C语言API。
我们平时所编写的OC代码,在程序运行时,最终都会转成Runtime的C语言代码,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才能根据函数名称找到对应的函数来调用。Runtime算是OC的幕后工作者,objc_msgSend。

2、Runtime使用场景

  • 一些OC不好实现或者无法实现的底层操作
  • 动态创建一个类(比如KVO的底层实现)objc_allocateClassPair,class_addlvar,objc_registerClassPair,例如:热创建
    在程度的运行过程当中,动态的为某个类添加属性/方法,修改属性/方法(修改第三方框架)objc_setAssociatedObject object_setlvar 例如:热更新
  • 遍历一个类的所有成员变量(属性)/所有方法(字典转模型、归解档)class_copyIvarList class_copyPropertyList class_copyMethodList 如YYmodel、MJextension、JsonModel
  • 查找对象 实现万能跳转跳转,例如收到推送的通知跳转到对应的页面

3、消息机制

3.1消息转发的原理

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

3.2、SEL isa super cmd
  • sel:一种类型,表示方法名称,类似字符串(可互转)
  • isa:在方法底层对象的objc_msgSend调用时,会更具isa找到对象所在的类对象,类对象中包含了调度表(dispatch table),该表就类的sel和方法的实际内存地址关联起来。
  • super_class:每一个累中还包含了一个super_class指针,用来指向父类对象。
  • IMP定义为id (*IMP) (id, SEL, …)。这样说来,IMP是一个指向函数的指针,这个被指向的函数包括id(“self”指针),调用的SEL(方法名),再加上一些其他参数.说白了IMP就是实现方法
3.3、动态绑定

在运行时确定要调用的方法

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

3.4当找不到方法的时候:

①、runtime首先进入动态方法分析获取IMP,调用 + resolveInstanceMethod 或 + resolveClassMethod 尝试获取 IMP。
②、没有IMP时,进入快速消息转发,进入快速消息转发,调用 - forwardingTargetForSelector: 尝试获取一个可以处理的对象。
③、仍没有处理,进入慢速转发,调用 - methodSignatureForSelector: 获取到方法签名后,将消息封装为一个invocation 再调用 - forwardInvocation: 进行处理。

4、动态添加属性
#import <objc/runtime.h>
/** <#注释#> */
@property (nonatomic,copy) NSString *name;

- (void)setName:(NSString *)name{
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)name{
    return objc_getAssociatedObject(self, @"name");
}

使用要引入分类头文件
#import "NSObject+son.h"
NSObject *objc = [[NSObject alloc] init];
    objc.name = @"text";

相关文章

  • runtime系列文章总结

    《iOS Runtime详解(消息机制,类元对象,缓存机制,消息转发)》《消息转发机制与Aspects源码解析》《...

  • Runtime 的应用

    前面我们说到:Runtime 消息传递机制Runtime 消息转发机制Runtime 交换方法今天我们来谈谈Run...

  • Effective Objective-C读后笔记(2)

    11、runtime消息转发机制 runtime的消息转发流程图消息转发 消息转发的示例实现 这里也给大家推荐一篇...

  • iOS - Runtime - 概念和方法交换

    runtime的概述runtime的相关概念runtime消息机制消息传递动态方法解析消息转发runtime的作用...

  • iOS消息转发机制

    消息转发机制: 消息转发机制是相对于消息传递机制而言的。 1、消息(传递)机制 RunTime简称运行时。就是系统...

  • Runtime知识点整理1

    OC消息机制?消息转发机制流程?什么是Runtime?什么场景下使用? ==============巴拉巴拉......

  • runtime消息转发机制

    消息转发机制基本上分为三个步骤: 1. 动态方法解析 2. 备用接收者 3. 完整转发 我们可以通过控制这三个步骤...

  • Runtime 消息转发机制

    在编译期,向对象或者类对象发送了其无法解读的消息并不会报错,因为在运行期可以继续向类和元类(metaClass)中...

  • runtime:消息转发机制

    若想令类能理解某条消息,我们必须以程序码实现出对应的方法才行。但是,在编译期向类发送了无法解读的消息并不会报错,因...

  • runtime消息转发机制

    Objective-C 扩展了 C 语言,并加入了面向对象特性和 Smalltalk 式的消息传递机制。而这个扩展...

网友评论

      本文标题:Runtime(消息转发机制)

      本文链接:https://www.haomeiwen.com/subject/ntezqltx.html