Object保留Objective-C类方法的行为

时间:2009-03-24 02:54:33

标签: objective-c static-members retain class-method

保留和释放传递给类方法的对象的最佳做法是什么?

例如,如果你有一个“类变量”声明如下:

static NSString *_myString = nil

......这是正确的做法:

+ (void)myClassMethod:(NSString *)param {
    _myString = param;
}

...其缺点是调用者需要在param上保持非零保留计数,以免过早释放。或者,可以这样做:

+ (void)myClassMethod:(NSString *)param {
    [_myString autorelease];
    _myString = [param retain];
}

...它的缺点是没有相应的类级别dealloc调用它会泄漏内存。或者是否应该完全避免这种类变量chicanery,也许使用一个以更传统的方式管理这些类型对象的生命周期的单例类?

以下是Apple's docs on creating a singleton instance

我正在使用的代码是非常灵活(但仍然是新的)Objective Resource项目(http://www.iphoneonrails.com/)。

2 个答案:

答案 0 :(得分:3)

绝对保留和释放。这不是泄漏,因为调用类dealloc的唯一时间是程序结束时 - 此时内存将被释放。第一种方式这样做会更麻烦,违背了Cocoa内存管理指南。

至于它应该是类方法还是单例:类本身通常不应该有很多独立的功能。它们只是在Objective-C中没有这样设计,正如您可以从缺少类变量中看到的那样。类方法通常应该处理创建和管理实例,有时还要存储所有实例的共享属性或默认值。类的实际功能应该进入实例。这是Objective-C中的惯例。

(当然,没有Objective-C上帝,你可以自由地忽略惯例,但那是一般智慧。)

答案 1 :(得分:3)

此外,对于NSString或任何具有可变变体的类(如NSArrayNSDictionary),我强烈建议您复制参数而不是保留它。如果调用者传递给你的字符串是NSMutableString,它的值可能会在以后更改,并且它也会在您的类中更改。这可能不是你想要的,所以我建议这样做:

+ (void)myClassMethod:(NSString *)param {
    [_myString release];
    _myString = [param copy];
}

copy方法制作副本并将保留计数设置为1,因此您只需保留变量即可。并且,作为一个额外的奖励,如果调用者确实通过了NSString,那么该类足够聪明,知道它的值不能改变,所以它只是保留自己以避免复制该对象。这有多聪明?