2009-09-25 192 views
0

有了一个实例变量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(可能因为变量已被分配),则较长版本更好。这是部分原因吗?

谢谢。

+2

您将方法命名为'init'完全是误导性的,因为它们都不具备远程资格作为ini tializer。 – bbum 2009-09-25 04:08:43

回答

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 
+0

感谢您的回答,它为我解决了一些问题。 – 2009-09-28 08:24:55

0

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

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

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

随着第一个样式,静态方法执行上有一个分配/初始化/自动释放给你,让你不不必。使用第二种方式,您可以更好地控制何时释放内存,而不是在退出当前块时自动释放内存。

-1

该代码会导致应用程序崩溃。第二个版本只复制指针然后释放实例。在发布参考资料之前,您需要致电[object retain]

1

这是一个习语用在mutators(有时称为“setters”),但我认为你输入它有点不对。通常看起来像这样:

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

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