设置属性值时不必要的临时变量?

Ken*_*nny 3 iphone properties objective-c

我正在阅读一本关于iPhone开发的书,我在示例代码中看到的特定模式对我来说没有多大意义.无论何时设置属性,它们首先为该属性的新值指定一个指针,然后将该属性设置为指针,然后释放指针.例:

接口:

@interface DoubleComponentPickerViewController : UIViewController {
    NSArray *breadTypes;
}

@property(nonatomic, retain) NSArray *breadTypes;

@end
Run Code Online (Sandbox Code Playgroud)

分类方法:

- (void)viewDidLoad {
    NSArray *breadArray = [[NSArray alloc] initWithObjects:@"White", @"Whole Wheat", @"Rye", @"Sourdough", @"Seven Grain", nil];
    self.breadTypes = breadArray;
    [breadArray release];
}
Run Code Online (Sandbox Code Playgroud)

有没有理由这样做而不只是做以下事情?

- (void)viewDidLoad {
    self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @"Whole Wheat", @"Rye", @"Sourdough", @"Seven Grain", nil];
}
Run Code Online (Sandbox Code Playgroud)

感谢毫无疑问会消失的光芒:)

mah*_*udz 9

让我试着以不同的方式解释它.

在其名称中具有alloc,copy或new的方法将为对象分配内存,并将该对象的所有权赋予调用者,并且调用者有责任释放该内存.

在viewDidLoad方法中,调用一个方法,该方法为您提供对象的所有权.发布它是您的方法的责任.但是,在你这样做之前,你想要用它做一些事情 - 毕竟,这就是你分配它的原因,不是仅仅发布它,而是用它来做一些有用的事情.

无论你想用它做什么,你都必须释放它(或自动释放它*).在这种情况下,您对该对象的使用是将其传递给self.breadTypes.self.breadTypes可能看起来不像是一个方法,但它是(它是一个setter).你传递breadArray.它做了它需要的东西.它可能会保留它以供以后使用,或者它可能会复制一些信息,或者复制整个事物.你的viewDidLoad并不在乎.它假设self.breadTypes做它需要的东西,当它返回时,它不关心你用breadArray做什么.

而你用它做什么,就是你与你拥有的任何东西有关 - 释放(或自动释放*它).

这就是你必须使用temp变量breadArray的原因.你不能完全从同一行的alloc中释放结果,因为在self.breadTypes可以拥有它之前,该对象将被释放:

self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil] release];
Run Code Online (Sandbox Code Playgroud)

因此,您被迫分配给临时变量,将其传递给self.breadTypes,然后释放breadArray中保存的对象.

现在,您可以尝试这样做,因此您不使用临时变量:

- (void)viewDidLoad {
    self.breadTypes = [[NSArray alloc] initWithObjects:@"White", @..., nil];
    [self.breadTypes release];
}
Run Code Online (Sandbox Code Playgroud)

但这并不是非常有效,因为如果你刚刚将值存储在临时变量中,那么你正在调用另一种方法(self.breadTypes作为一个getter),你真的不需要它.

*现在,正如响应者所说,您可以使用autorelease作为替代版本:

- (void)viewDidLoad {
    self.breadTypes = [[[NSArray alloc] initWithObjects:@"White", ..., nil] 
                        autorelease];
}
Run Code Online (Sandbox Code Playgroud)

Apple敦促我们三思而后行,是否要使用autorelease与release.自动释放可能不是每种情况的最佳选择.我个人喜欢尽快清理自己,不要不必使用autorelease.自动释放的对象在运行循环执行结束时释放,例如在viewDidLoad返回后不久.你应该阅读更多关于自动释放(以及iPhone上的内存管理,这与MacOS X Cocoa略有不同),因为我过于简单了.

顺便说一句:如果你retain是一个对象,你就拥有它的所有权,并且release在完成它之后你将再次承担相同的责任.