OC底层原理14-0:方法调用的本质objc_msgSend消息发送
前言
我们先得出结论:方法调用的本质是 objc_msgSend消息发送
本文主要目的是理解 objc_msgSend
的 方法查找
流程
在上一篇文章中 OC底层原理13:cache-t底层原理分析 中,分析了 cache的写入流程
,在写入流程之前,还有一个 cache读取流程
,即 objc_msgSend
和 cache_getImp
在分析之前,首先了解什么是 Runtime
Runtime介绍
runtime成为运行时,它区别于编译时:
运行时
是代码跑起来,被装载到内存中
的过程,如果此时出错,则程序会崩溃,是一个动态
阶段编译时
是源代码编译成机器能识别的代码
的过程,主要是对语言进行最基本的检查报错,即词法分析、语法分析
等,是一个静态
的阶段
runtime
的 使用
有以下三种方式,其中三种实现方式与编译层和底层的关系如下所示:
通过
OC代码
,例如[person sayNB]
通过
Framework&Service
,例如isKindOfClass
通过
Runtime API
,例如class_getInstanceSize
complier
就是我们了解的编译器
,即LLVM
,例如OC
的alloc
对应底层的objc_alloc
runtime system library
就是Runtime 底层库
。可以通过
command + shift + 0
打开官方文档
探索方法的本质
方法的本质
在 OC底层原理08:isa和类关联探索 文章中,通过 clang
编译的源码,理解了 oc对象的本质
,同样的,使用clang
编译 main.m -> main.cpp
文件,通过查看main函数中方法调用的实现,如下所示
- mian.m 内实现如下代码:
1 | // 👇main.m中 |
- 终端
clang
编译miam.m -> main.cpp
后的代码
1 | // 👇clang编译后的底层实现 |
总结: 通过上述代码可以看出,方法的本质
就是 objc_msgSend消息发送
验证方法本质
方法:消息(消息的接受者,消息主体)
- 为了验证,通过
objc_msgSend
方法来完成[person sayNB]
的调用,查看其打印是否一致
1 | 注:👇 objc_msgSend 消息发送流程是在 <objc/message.h> 系统库中 |
- 再次编译运行
command + R
1 | ZJPerson * person = [ZJPerson alloc]; |
其打印结果如下,发现是一致的,所以 [person sayNB]
等价于 objc_msgSend(person,sel_registerName("sayNB"))
子类对象方法调用-执行父类的实现
- 首先我们定义两个类
子类ZJStudent
和父类ZJPerson
1 | // 父类 ZJPerson |
- 在
main.m
中让子类调用sayNB
方法,查看是否能输出结果
1 | ZJPerson * person = [ZJPerson alloc]; |
运行程序,查看结果
由打印结果可知,子类方法的调用,可以 执行父类方法的实现
那么子类是如何调用父类的方法实现的呢?我们往下探索
子类调用父类方法的原理
我们先说结论:我们还可以尝试让 person
的调用执行父类中的实现,通过 objc_msgSendSuper
实现
- 在
main.m
函数中的调用
1 | ZJPerson * person = [ZJPerson alloc]; |
进入objc_msgSendSuper内,查看一下结构
由上图可知 objc_msgSendSuper
方法中有两个参数 (结构体,sel)
,其结构体类型是 objc_super
定义的结构体对象,且需要指定 receiver
和 super_class
两个属性
- 运行程序,查看打印结果:
1 | 2023-02-25 16:31:22.959805+0800 msg_seng继承父类[53476:1503775] 666 |
由打印结果,我们发现不论是 [person sayHello]
还是 objc_msgSendSuper
都执行的是 父类
中的 sayHello
的实现,所以这里,我们可以可以猜想:方法调用、首先是在类中查找,如果类中没有找到,会到父类中查找。
总结
由上面的结论我们知道
方法的调用
实际上是消息发送objc_msgSend
在 c 中,可以直接调用
函数
在 OC 中,方法调用是消息发送,消息发送objc_smgSend是通过
sel方法编号
找到imp函数指针地址
,进而找到内容
- Post title:OC底层原理14-0:方法调用的本质objc_msgSend消息发送
- Post author:张建
- Create time:2023-02-25 16:41:30
- Post link:https://redefine.ohevan.com/2023/02/25/OC底层原理/OC底层原理14-0:方法调用的本质objc_msgSend消息发送/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.