返回
objc_msgSend底层汇编解析,揭秘iOS消息发送机制
IOS
2024-01-07 08:49:35
前言
在上一篇文章中,我们探讨了 Runtime
的基础知识,以及与 Runtime
交互的三种方式。我们还总结道:方法的本质实际上是消息发送的过程
。本文将继续深入探讨 objc_msgSend
的汇编实现,揭开 iOS 消息发送机制的神秘面纱。
汇编实现剖析
objc_msgSend
是 Objective-C 中用于发送消息的核心函数。它是一个汇编函数,它的实现可以在 iOS 系统的 objc-runtime.h
头文件中找到。其原型如下:
id objc_msgSend(id self, SEL op, ...);
其中:
self
:要向其发送消息的对象。op
:要发送的消息选择器。...
:要传递给消息处理程序的可选参数。
objc_msgSend
函数的汇编实现可以分解为以下步骤:
-
查找方法实现:
- 从对象
self
的类中查找与消息选择器op
相对应的实现方法。 - 如果找不到匹配的方法,则尝试通过消息转发机制查找实现。
- 从对象
-
压栈参数:
- 将消息选择器
op
压入栈中。 - 将消息接收者
self
压入栈中。 - 将可选参数(如果有)压入栈中。
- 将消息选择器
-
调用方法实现:
- 调用方法实现的地址,该地址通过步骤 1 中的查找获得。
- 方法实现将从栈中弹出参数并执行消息处理。
-
返回值:
- 方法实现执行完成后,将返回值压入栈中。
objc_msgSend
函数返回栈顶的值。
实例分析
为了更深入地了解 objc_msgSend
的工作原理,让我们编写一个示例程序并对其汇编代码进行分析。
#import <Foundation/Foundation.h>
@interface Person : NSObject
- (void)sayHello;
@end
@implementation Person
- (void)sayHello {
NSLog(@"Hello, world!");
}
@end
int main() {
Person *person = [[Person alloc] init];
[person sayHello];
return 0;
}
使用 xcrun -sdk iphoneos clang -arch arm64 -S -o assembly.s main.m
命令将此程序编译成汇编代码。然后,我们可以使用 grep
命令查找 objc_msgSend
函数的汇编实现:
grep objc_msgSend assembly.s
输出结果将显示 objc_msgSend
函数的汇编代码,我们可以从中看到函数执行的步骤,正如我们在前面所讨论的。
总结
通过分析 objc_msgSend
的汇编实现,我们可以深入了解 iOS 消息发送机制。我们了解到 objc_msgSend
负责查找方法实现、压栈参数、调用方法实现并返回结果。这种对底层机制的理解有助于我们编写出更健壮、更高效的 Objective-C 代码。