返回

从源码剖析NSObject的alloc方法为何不走源码工程

IOS

Objective-C alloc 方法的秘密

在 Objective-C 中,alloc 方法用于为一个类创建一个新的实例。但是,alloc 方法在 NSObject 和自定义类中的实现却大不相同。本文将深入探索这些差异,揭开 alloc 方法背后的秘密。

NSObject 的 alloc 方法

NSObject 的 alloc 方法位于 Objective-C 运行时库中,是一个类方法,用于创建该类的实例。它调用 allocWithZone: 方法来分配内存并创建对象,然后调用 initWithZone: 方法来初始化对象。

+ (instancetype)alloc {
    return [[self allocWithZone:NULL] initWithZone:NULL];
}

allocWithZone: 方法负责为对象分配内存。它调用 NSAllocateObject 函数,该函数在 Objective-C 运行时库中定义,以分配指定大小的内存。

+ (instancetype)allocWithZone:(NSZone *)zone {
    return NSAllocateObject(self, 0, NULL);
}

initWithZone: 方法负责初始化对象。它返回 self,表明没有执行额外的初始化操作。

- (instancetype)initWithZone:(NSZone *)zone {
    return self;
}

自定义类的 alloc 方法

自定义类的 alloc 方法位于类的实现文件中,也是一个类方法。它调用 super alloc 来创建该类的父类的实例。

- (instancetype)alloc {
    return [super alloc];
}

super alloc 是一个指向父类 alloc 方法的指针。

比较

NSObject 的 alloc 方法与自定义类的 alloc 方法之间存在几个关键差异:

  • 位置: NSObject 的 alloc 方法位于运行时库中,而自定义类的 alloc 方法位于实现文件中。
  • 内存分配: NSObject 的 alloc 方法调用 allocWithZone: 方法来分配内存,而自定义类的 alloc 方法调用 super alloc,最终调用父类的 alloc 方法。
  • 初始化: NSObject 的 alloc 方法调用 initWithZone: 方法来初始化对象,而自定义类的 alloc 方法没有执行额外的初始化。

结论

NSObject 的 alloc 方法不走源码工程的原因在于其位置和实现的差异。它位于运行时库中,并采用不同的方式分配内存和初始化对象。另一方面,自定义类的 alloc 方法位于实现文件中,并依赖于父类的 alloc 方法来创建和初始化实例。

常见问题解答

  • 为什么 NSObject 的 alloc 方法不调用 super alloc
    因为 NSObject 没有父类。

  • 自定义类的 alloc 方法可以执行额外的初始化吗?
    可以,通过覆盖父类的 alloc 方法。

  • allocWithZone: 方法有什么作用?
    它允许您指定一个内存区域来存储对象。

  • initWithZone: 方法有什么作用?
    它允许您在创建对象后进行自定义初始化。

  • 如何查看 alloc 方法的实际实现?
    您可以使用 Objective-C Runtime 函数 class_getMethodImplementation 来查看 alloc 方法的实现。