返回

探秘OC对象alloc和init的源码机制:lldb调试与objc源码分析

IOS

引言:

在Objective-C开发中,对象分配和初始化是至关重要的基础概念。alloc和init方法负责创建和配置对象实例,为程序中的各种操作奠定基础。本文将深入探索alloc和init的底层机制,通过阅读objc源码和设置lldb断点进行调试分析,揭开它们的运作方式。

1. alloc方法:对象分配

alloc方法负责分配一个指定类的新对象。它的实现位于objc-runtime.h头文件中:

id objc_alloc(Class cls);

当调用alloc方法时,它会执行以下步骤:

  • 向操作系统请求一块足够大小的内存空间来容纳对象实例。
  • 在分配的内存中创建一个对象,该对象包含指向其类的指针和一些内部数据结构。

alloc方法返回指向新创建对象的指针,该指针类型为id,可以转换为任何Objective-C对象类型。

2. init方法:对象初始化

init方法负责初始化新创建的对象。它的实现位于每个类的实现文件中,通常如下所示:

- (instancetype)init {
    if (self = [super init]) {
        // 初始化代码
    }
    return self;
}

init方法执行以下步骤:

  • 调用父类的init方法(如果存在)。
  • 如果父类的init方法成功,则执行自定义初始化代码。
  • 返回指向初始化后的对象的指针。

init方法可以被子类覆盖,以提供特定于该子类的自定义初始化逻辑。

3. 源码分析:

我们使用lldb调试器和objc源码来分析alloc和init的内部机制。

lldb调试:

(lldb) br s -n alloc
(lldb) br s -n init
(lldb) r

这将设置断点以在执行alloc和init方法时暂停程序。

objc源码:

在objc-runtime.h中,我们找到了alloc方法的实现:

id objc_alloc(Class cls) {
    id obj;

    if (class_isMetaClass(cls))
        obj = objc_allocMetaClass(cls);
    else {
        size_t size = class_getInstanceSize(cls);
        obj = calloc(1, size);
        memset(obj, 0, size);
        ((id)obj)->isa = cls;
    }

    return obj;
}

这个实现显示了如何分配内存、初始化对象并将其isa指针设置为其类。

在类实现文件中,我们找到了init方法的实现:

- (instancetype)init {
    if (self = [super init]) {
        // 初始化代码
    }
    return self;
}

这个实现展示了如何调用父类的init方法,执行自定义初始化代码,然后返回指向初始化后的对象的指针。

4. 内存分析:

使用lldb的lldb命令,我们可以分析alloc方法分配的内存:

(lldb) p (uint64_t)self
(lldb) memory read --size 16 --format x

这将显示分配的内存的十六进制转储,其中包含指向类的指针、引用计数和其他内部数据。

5. 结论:

通过阅读objc源码和设置lldb断点进行调试分析,我们深入了解了alloc和init方法的底层机制。这些方法负责创建和初始化Objective-C对象,为应用程序中的各种操作提供基础。掌握这些机制对于理解Objective-C内存管理和对象生命周期至关重要。