返回
iOS底层之旅——揭秘OC对象原理(下)
IOS
2023-11-12 23:54:22
在探索iOS底层神秘莫测的黑洞世界时,我们曾尝试从一个熟悉却陌生的角度——OC对象,来揭开其神秘面纱。然而,途中不断衍生的疑问让我们意识到,仅凭已有的知识还无法深入探究。于是,我们踏上了新的征程,借助LLDB、汇编、符号断点的强大力量,继续深入iOS底层,寻求OC对象原理的真谛。
汇编指令的秘密
通过LLDB的disassemble命令,我们可以将OC代码转换成底层的汇编指令。让我们以一个简单的OC对象实例化为例:
NSObject *object = [[NSObject alloc] init];
对应的汇编指令如下:
mov rax, QWORD PTR [rip+0x1f4] ; mov rax, _objc_msgSend
mov rdi, r12 ; mov rdi, self
mov rsi, QWORD PTR [rip+0x1e8] ; mov rsi, _objc_msgSend_stret
call rax
仔细观察,我们可以发现以下关键点:
_objc_msgSend
函数被调用,它负责将消息发送给对象。self
(r12
寄存器)和_objc_msgSend_stret
(rsi
寄存器)作为参数传递。
符号断点的强大之处
符号断点允许我们在程序执行到特定符号时暂停执行。通过在_objc_msgSend
函数上设置符号断点,我们可以深入了解消息发送的过程。
当程序在断点处暂停时,我们可以使用LLDB的frame variable
命令查看函数参数:
(lldb) frame variable self
self = 0x7ffeefbfb230 <NSObject: 0x7ffeefbfb230>
可以看到,self
参数指向了我们实例化的OC对象。
探寻对象布局
借助汇编指令和符号断点的帮助,我们进一步探索了OC对象在内存中的布局。
- ISA指针: 每个OC对象都包含一个指向其类
ISA
结构的指针,该结构包含了对象方法、实例变量和其他元信息。 - 实例变量: 对象实例变量紧跟在ISA指针之后存储。
- 引用计数: 每个对象都有一个引用计数,表示有多少变量或指针指向它。
结论
通过深入探索LLDB、汇编和符号断点,我们揭开了iOS底层OC对象原理的神秘面纱。我们了解了消息发送机制、符号断点的使用方法以及OC对象在内存中的布局。这些知识为我们进一步探索iOS底层提供了坚实的基础。