【发布时间】:2014-03-17 08:28:24
【问题描述】:
显然我不只是指 NSString;有[NSDictionary dictionary]、[NSArray array] 等等。但是,当我们可以发送[NSDictionary new]、[NSArray new] 等时,为什么还要使用所有这些方法呢?
【问题讨论】:
标签: cocoa-touch cocoa constructor
显然我不只是指 NSString;有[NSDictionary dictionary]、[NSArray array] 等等。但是,当我们可以发送[NSDictionary new]、[NSArray new] 等时,为什么还要使用所有这些方法呢?
【问题讨论】:
标签: cocoa-touch cocoa constructor
原因主要是历史原因,因为两者的区别在于创建对象的引用计数;自动引用计数几乎完全消除了对引用计数的关心。
+string and methods like it 返回不属于调用者的对象(它们在自动释放池中)。另一方面,+new 是 "four NARCs" 之一,它确实创建了拥有引用。
在 ARC 之前,您会选择在特定情况下具有您需要的内存管理含义的那个。现在,您可以使用任何您喜欢的。您的代码级别没有区别。
在某些循环情况下,您可能会发现使用+new 更可取,因为与+string 相比,still does apparently 缩短了对象的生命周期。
【讨论】:
new 是 ARC 的首选,因为这样在分配大量代码块时就不需要@autoreleasepool { ... }。
objc_retainAutoreleasedReturnValue() 可以避免这种情况。
补充 Josh 的好答案,在使用 ARC 时,首选使用 alloc] init] 或 new,因为您不再需要 @autoreleasepool { ... } 来释放自动释放压力。
考虑以下代码:
for(int i = 0; i < X; i++)
{
//@autoreleasepool {
NSMutableArray* array = [NSMutableArray array];
for(int j = 0; j < Y; j++)
{
[array addObject:[NSString stringWithFormat:@"%d", j]];
}
///Do something with array.
//}
}
随着X 和Y 的增长,您会发现内存在增长,并且需要@autoreleasepool,因为只有在自动释放池耗尽时才会释放对象。
现在考虑
for(int i = 0; i < X; i++)
{
NSMutableArray* array = [NSMutableArray new];
for(int j = 0; j < Y; j++)
{
[array addObject:[[NSString alloc] initWithFormat:@"%d", j]];
}
///Do something with array.
}
这里的对象一旦超出范围就会被释放并且不再保留。
【讨论】:
[NSDictionary dictionary]、[NSArray array]等方法,返回autoreleased对象。这意味着您没有这些对象的所有权,并且您无需担心内存管理。
当您使用 new 或 alloc 时,您需要在使用完毕后释放这些对象。
当您不使用 ARC 时,这种区别很重要。
【讨论】:
new 不返回 autoreleaed 对象。