是否需要在Objective-C中覆盖+ alloc?

时间:2009-09-03 04:06:36

标签: objective-c memory-management

基于对this question的一些答案,似乎+ alloc为Objective-C中的对象实例分配内存做了一些幕后魔术。是否需要覆盖+ alloc?

3 个答案:

答案 0 :(得分:7)

这是非常罕见的。

NSString是一个覆盖+ alloc作为实现细节的类的示例。如果你要检查,你会发现+ [NSString alloc]返回NSPlaceholderString类。这是字符串class cluster的实现的一部分。

你也可以覆盖从不同的分配中分配NSZone是默认的。或者,您可以像extraBytes那样使用非{0}来调用NSAllocateObject这样的技巧,以便在您的ivars之后提供动态的空间量。例如,你可能认为你通常最终得到的NSString的私有子类看起来像这样:

@interface {
    NSUInteger length;
    unichar *data;
}

但事实并非如此。它是一个包含长度和字符数据的单个内存块。不同的NSString实例是不同大小的内存块。这是您可以通过直接调用NSAllocateObject来安排的事情。

但所有这些都是诡计和黑客行为。如果你覆盖+ alloc,那就会发生一些特别的事情。

答案 1 :(得分:4)

+alloc没有做任何魔术,它只是在Objective-C运行时调用一个方法来获取类实例的大小并分配该内存量。在编写真正的单例时,您可能希望覆盖+alloc(即,您希望保证只能分配您的类的单个实例)。虽然在编写单例类时很少需要达到这些长度,但你可以。通常,您将覆盖+alloc以提供替代方法(例如,不在不同区域中分配内存,分配与接收类不同的类 - 这是类集群可能执行的操作)行为,或者您可以调用{{1}要做标准工作,然后添加自己的自定义。

答案 2 :(得分:1)

我覆盖了Singleton类的alloc,例如:

#import "Singleton.h"

static Singleton * instance;

@implementation Singleton

+ (void)initialize
{
    if (!instance) {
        instance = [[super allocWithZone:NULL] init];
    }
}

+ (id)allocWithZone:(NSZone * const)notUsed
{
    return instance;
}

@end