美文网首页
消息机制和runtime的相关应用

消息机制和runtime的相关应用

作者: 牛奶红茶 | 来源:发表于2021-03-11 15:18 被阅读0次

1.objc_msgSend执行流程

-OC中的方法调用其实就是转成objc_msgSend函数的调用,给receiver(方法调用者)发送了一条消息(selector方法名)

-objc_msgSend的执行流程可以分为3大阶段

->1.消息发送

消息发送流程

消息发送给方法查找的流程

对象方法流程

对象的实例方法-自己有-返回自己

对象的实例方法-自己没有-父类有-返回父类的

对象的实例方法-自己没有-父类也没有-找父类的父类-NSObject有-返回NSObject的

对象的实例方法-自己没有-父类也没有-找父类的父类-NSObject也没有-崩溃

类方法流程

类方法-自己有-返回自己

类方法-自己没有-父类有-返回父类的

类方法-自己没有-父类也没有-找父类的父类-NSObject有-返回NSObject的

类方法-自己没有-父类也没有-找父类的父类-NSObject也没有--但是有对象方法-返回对象方法

类方法-自己没有-父类也没有-找父类的父类-NSObject也没有--对象方法也没有-崩溃

而类方法找到最后没有找到但是NSObject的对象方法有重名则执行对象方法,这条则是下图中(meta)Root class指向(class)Root class的体现

类的结构体系

->2.动态方法解析

动态方法解析(动态添加方法实现)

是否曾经有动态解析->曾经有动态解析->直接走消息发送

是否曾经有动态解析->未有动态解析->调用+ (BOOL)resolveClassMethod:(SEL)sel,或+ (BOOL)resolveInstanceMethod:(SEL)sel来动态解析方法,->标记威已经动态解析->走消息发送(动态解析后,会重新走消息发送流程,即"从receiverClass的cache中查找方法"这一步开始执行)

->3.消息转发

消息转发的流程(以上方法都有对象方法和类方法两个版本,类方法只需要在前面加+即可)

- (id)forwardingTargetForSelector:(SEL)aSelector 如果返回一个类,则会在该类中处理aSelector方法

- (void)forwardInvocation:(NSInvocation *)anInvocation 一旦执行到该方法中,则可以在该方法里自定义任何逻辑,消息到此也就结束了,并不会导致崩溃

2.Runtime相关

->1.什么是Runtime?平时项目中使用过吗?

--OC是一门动态性比较强的编程语言,允许很多操作推迟到程序运行时再进行

--OC的动态性就是由Runtime来支撑和实现的,Runtime是一套C语言的API,封装了很多动态性相关的函数,平时编写的 OC代码,底层个都是转成Runtime API进行调用

->2.Runtime的具体应用

--利用关联对象(AssociatedObject)给分类添加属性

--遍历类的所有成员变量(秀尴尬癌textfield的占位文字颜色,字典转模型,自动归档解档)

--交换方法实现(交换系统的方法,可以防止数组越界,字典设置空崩溃等)

--利用消息转发机制解决方法找不到的异常问题

3. 能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?

不能向编译后得到的类中增加实例变量,因为编译后的类已经注册到runtime中,类的结构体中的objc_ivar_list实例变量的链表和instance_size实例变量的内存大小已经确定,同时runtime会调用class_setIvarLayout或class_setWeakIvarLayout来处理strong weak 引用,所哟不能向存在的类中添加实例变量

可以向运行时创建的类中添加实例变量,调用class_addIvar函数,但是必须要在调用objc_allocateClassPair之后,在objc_registerClassPair之前。其实就是在编译过程中添加实例变量,编译后类的实例链表,方法链表,变量大小都已经确定了

4.SEL和Method,IMP

objc_method

objc_method结构体中的内容

SEL method_name 方法名

char *method_types方法类型

IMP method_imp 方法实现

SEL

SEL  typedef struct objc_selector *SEL 代表方法的名称,翻译成选择子或选择器,代表方法在Runtime期间的标识符,objc_selector结构体本质上上时一个个C字符串。在类加载的时候,编译器会生成与方法相对应的选择子,并注册大奥objective-C的Runtime运行系统,不论两个类是否存在依存关系,只要他们拥有相同的方法名,返回值等,那么他们的SEL就是相同的

SEL sel = @selector(methodName)

IMP

IMP :typedef id (*IMP)(id, SEL, ...),代表函数指针,即函数执行的入口,该函数使用标准的C调用,第一个参数支向self(它代表当前类实例的地址,如果是类则指向的是它的元类),作为消息的接受者,第二个参数代表选择子(选择器),......代表可选参数,前面的id代表返回值

Method

Method typedef struct objc_method *Method Method对开发者来说是一种不透明的类型,被隐藏在我们平时书写的类或对象的方法背后,他是一个objc_method结构体指针,该结构体中包含一个SEL和IMP,实际上相当于在SEL和IMP做了一个映射,有了SEL我们可以找到IMP,从而调用方法的实现代码

方法名method_name类型为SEL,前面提到过相同名字的方法即使在不同类中定义,它们的方法选择器也相。方法类型method_types是个char指针,其实存储着方法的参数类型和返回值类型,即是Type Encoding编码。method_imp指向方法的实现,本质上是一个函数的指针

5.runtime 如何通过selector找到对应的IMP地址?

实例方法:每个实例的isa指针指向着对应类对象,而每一个类对象中都有一个对象方法列表

类方法:每个类对象的isa指针都指向着对应的元类对象,而每一个元类对象中都有一个类方法列表

->当我们发送一个消息给一个NSObject对象时,这条消息会在对象的类对象方法列表里查找

->当我们发送一个消息给一个类时,这条消息会在类的meta class对象的方法别表里查找

在寻找IMP的地址时,runtime提供管理两种方法

1.IMP class_getMethodImplementation(Class cls, SEL name);

2.IMP method_getImplementation(Method m)

第一中方法,类方法和实例方法实际上都是通过调用class_getMethodImplementation()来寻找IMP地址的,不同之处在于传入的第一个参数不同,通过传入的参数不同,找到不同的方法劣币啊嗷,方法列表中保存着方法信息的结构体(objc_method),结构体中包含方法的实现,selector本质就是方法的名称,通过该方法名称,即可在结构体中找到相应的实现

类方法(假设有一个类A)

class_getMethodImplementation(objc_getMetaClass("A"),@selector(methodName));

实例方法

class_getMethodImplementation([A class],@selector(methodName));

第二种方法,传入的参数只有method,区分类方法和实例方法在于封装method的函数

类方法

Method class_getClassMethod(Class cls, SEL name)

实例方法

Method class_getInstanceMethod(Class cls, SEL name)

最后调用 IMP method_getImplementation(Method m)获取IMP地址

---

---

---

===

相关文章

  • 消息机制和runtime的相关应用

    1.objc_msgSend执行流程 -OC中的方法调用其实就是转成objc_msgSend函数的调用,给rece...

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

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

  • Runtime那些事儿(消息机制)

    Runtime那些事儿(消息机制) Runtime那些事儿(消息机制)

  • Runtime的应用

    Runtime的基本属性和消息转发机制已经介绍过了,下面来了解一些Runtime提供的api在实际项目中的应用。 ...

  • iOS runtime

    runtime 是 oc 语音的基础首先runtime的核心机制是消息机制 也就是oc的消息机制首先oc的消息机制...

  • Runtime应用系列:消息机制

    OC中都是通过[MyClass classMethod]调用一个方法。而它的底层实现如何呢?接下来写一个简单的方法...

  • Runtime 的应用

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

  • Runtime—实战篇

    目录: Runtime简介 runtime实战应用代码一:OC代码对象调用代码 -> 消息发送机制代码 的转换代码...

  • OC-Runtime-Class结构和OC消息机制

    OC - Runtime - Class 结构 和 OC 消息机制 Runtime 源码中 Class 结构如下:...

  • 深入浅出Runtime

    Runtime运行时 目录 一、runtime 简介二、消息机制<了解>2.1 消息机制原理2.2 消息调用流程三...

网友评论

      本文标题:消息机制和runtime的相关应用

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