初始化实例变量

时间:2009-09-25 02:31:51

标签: objective-c cocoa variables

使用实例变量myArray:

@interface AppController : NSObject
{
    NSArray *myArray;
}

有时候我会看到myArray像这样初始化:

- (void)init
{
    [super init];
    self.myArray = [[NSArray alloc] init];
    return self;
}

有时我会用更复杂的方法看到它:

- (void)init
{
    [super init];
    NSArray *myTempArray = [[NSArray alloc] init];
    self.myArray = myTempArray
    [myTempArray release];
    return self;
}

我知道最终结果没有区别,但为什么人们会费心去做更长的版本呢?

我的感觉是,如果使用@property和@synthesize设置实例变量,则较长的版本会更好(可能因为已经分配了变量)。这是部分原因吗?

感谢。

4 个答案:

答案 0 :(得分:2)

如果myArray是属性并且设置为retaincopy(因为它应该属于这样的属性),那么您最终会双重保留变量当你这样做时:

self.myArray = [[NSArray alloc] init];

alloc调用将引用计数设置为1,属性赋值将保留或复制它。 (对于不可变对象,copy通常只是对retain的调用;不需要复制无法更改其值的对象。因此,在赋值后,对象具有保留计数2,即使你只持有一个引用它。这会泄漏记忆。

我希望看到直接分配给实例变量

myArray = [[NSArray alloc] init];

或正确处理保留计数:

NSArray *newArray = [[NSArray alloc] init];
self.myArray = newArray;
[newArray release];

或使用自动释放的对象:

self.myArray = [[[NSArray alloc] init] autorelease]; // Will be released once later
self.myArray = [NSArray array]; // Convenience constructors return autoreleased objects

答案 1 :(得分:1)

这是mutator中使用的习惯用语(有时称为“setter”),但我认为你输错了。通常它看起来像这样:

-(void)setMyName:(NSString *)newName
{
    [newName retain];
    [myName release];
    myName = newName;
}

保留新名称,因为此实例需要保留它;旧名被释放;最后,实例变量被指定为指向新名称。

答案 2 :(得分:0)

我有一种感觉,你的意思是:

NSArray* a = [NSArray arrayWithObjects:@"foo", @"bar", nil];

和这个

NSArray* a = [[NSArray alloc] initWithObjects:@"foo", @"bar", nil];
//...
[a release];

使用第一种样式,静态方法会为您执行alloc / init / autorelease,因此您不必这样做。使用第二种样式,您可以更好地控制释放内存的时间,而不是在退出当前块时自动释放。

答案 3 :(得分:-1)

该代码会使您的应用程序崩溃。第二个版本只复制指针然后释放实例。在发布引用之前,您需要调用[object retain]