从源码剖析NSObject的alloc方法为何不走源码工程
2023-12-07 17:27:48
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
方法的实现。