返回

iOS底层之旅——揭秘OC对象原理(下)

IOS

在探索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函数被调用,它负责将消息发送给对象。
  • selfr12寄存器)和_objc_msgSend_stretrsi寄存器)作为参数传递。

符号断点的强大之处

符号断点允许我们在程序执行到特定符号时暂停执行。通过在_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底层提供了坚实的基础。