返回

揭开 Objective-C `alloc` 和 `init` 实现的神秘面纱:汇编视角

IOS

为了深入理解 Objective-C 语言的基础,让我们踏上汇编之旅,探索 allocinit 方法背后的奥秘。

alloc:分配实例内存

alloc 方法负责分配一个指定类的新实例的内存。汇编代码如下:

_objc_msgSend_stret    // objc_msgSend 的延伸版本
mov r0, r3            // 将类对象地址移到 r0
ldr r1, [r0, #0x18]    // 从类对象加载实例大小偏移量
bl malloc              // 分配实例内存
str r0, [r2, #0x0]     // 将分配的内存地址存储在 this 指针中
mov r0, r2            // 将 this 指针移到 r0

此汇编代码首先调用 objc_msgSend 来发送 alloc 消息给类对象。然后,它从类对象加载实例大小,并调用 malloc 分配该大小的内存。分配的内存地址存储在 this 指针中,该指针指向新实例的内存区域。

init:初始化实例

init 方法负责初始化新分配的实例。汇编代码如下:

_objc_msgSend_stret    // objc_msgSend 的延伸版本
mov r0, r2            // 将 this 指针移到 r0
mov r1, r3            // 将类对象地址移到 r1
bl objc_msgSend       // 发送 init 消息给 this 指针
mov r0, r2            // 将 this 指针移到 r0

此汇编代码发送 init 消息给 this 指针,该指针指向新分配的实例。objc_msgSend 调用适当的方法来初始化实例的成员变量。

示例:CTStudent 类

让我们使用 CTStudent 类的一个示例来进一步说明:

@implementation CTStudent
- (instancetype)init {
    self = [super init];
    if (self) {
        // 初始化实例变量
    }
    return self;
}
@end

对于这个示例,init 方法的汇编代码将类似于以下内容:

_objc_msgSend_stret    // objc_msgSend 的延伸版本
mov r0, r2            // 将 this 指针移到 r0
mov r1, #class(CTStudent) // 将 CTStudent 类对象地址移到 r1
bl objc_msgSend       // 发送 superinit 消息给 this 指针
mov r0, r2            // 将 this 指针移到 r0

此汇编代码首先发送 superinit 消息给 this 指针,初始化 CTStudent 类的超类(通常是 NSObject)。然后,它执行任何特定于 CTStudent 类的初始化。

结论

通过汇编视角,我们深入了解了 Objective-C allocinit 方法背后的实现细节。这些方法对于分配实例内存和初始化实例变量至关重要,是理解 Objective-C 内存管理和对象生命周期基础的基石。