NSMutableArray arrayWithCapacity vs initWithCapacity

时间:2010-06-28 05:08:28

标签: iphone objective-c memory-management

我是一名拥有广泛Java背景的iPhone / Objective-C新手。

我在Objective-c中学到更多关于内存管理的知识,我正在阅读Apple关于内存管理的文档:http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

在“对象所有权策略”部分中,它表示您拥有通过以alloc,new或contains副本开头的方法创建的任何对象。所有权意味着您需要在完成后明确release该对象。

所以我正在查看NSMutableArray文档:http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html

有两种方法几乎可以做同样的事情......它们都创建了一个具有一些初始容量的数组。一个是类方法,另一个是实例方法。

+ (id)arrayWithCapacity:(NSUInteger)numItems;
- (id)initWithCapacity:(NSUInteger)numItems;

现在我是懒惰的Java开发人员,为什么我会在类方法上选择实例方法,因为我知道在某些时候我必须自己清理?

我想我可能在这里错过了一个基本点...它只是确定何时对象被释放?类方法中的autorelease与实例方法中的release相对应?我想在资源非常有限的平台(iPhone)上我应该避免使用类方法并在完成后立即释放对象?

谢谢!

3 个答案:

答案 0 :(得分:9)

您通常会根据您是否拥有超过当前方法生命周期的对象来选择(例如,将其分配给某些静态或直接分配给ivar)。在这种情况下,您可以使用alloc / init方法,因为您知道您已经拥有它。如果您打算仅将其用于当前方法的范围,或者将其分配给像属性一样管理的东西,那么您可能会使用方便方法。

当你知道你将拥有一个你正在创建的对象时,alloc / init调用总是比方便/保留方式更有效,因为后者需要基本上alloc / init / autorelease对象然后你在退货时保留它。

当您在循环中分配并且不需要/想要处理自动释放池时,您也可以使用直接alloc / init方法。

答案 1 :(得分:6)

arrayWithCapacity:已经应用了自动释放。

initWithCapacity:被明确保留,您需要自己发布它。因为你通常将它称为[[A alloc] init ...],这将触发一个灯泡“我需要为此管理内存”,除了“alloc”之外的其他类似的魔术词是“new”和“copy”as你在内存管理指南中读到。但是从你的问题来看,看起来你很了解它的原理。

你是正确的,你应该保持你的内存占用和低,但这并不意味着你需要始终做显式的初始化/释放。正如Nick所说,使用自动释放工厂方法的一个用例是当你将它们作为参数传递时。

另一个例子是,当您向NSDictionary或NSArray等集合添加内容时,可以使用autorelease factory方法创建“某些内容”,因为集合“接管”保留它。 (添加到集合时会保留,并在删除时释放。)

你可能会认为

Blah *blah = [Blah blahWithSomething];
[myMutableArray addObject:blah];
输入比

更干净
Blah *blah = [[Blah alloc] initWithSomething];
[myMutableArray addObject:blah];
[blah release];

在第一种情况下,您根本不需要担心发布呼叫。缺点是,当你在同一个runloop中多次这样做时,第一种情况下的内存占用量会更大,如果它是一个临时/一次性数组对象,它会在runloop结束时消失。但是如果它是一个小的物体没有在一个循环中完成并保留较长时间,这是一个常见的情况,他们的足迹是相同的。

答案 2 :(得分:0)

在这种情况下,我尝试遵守以下规则以避免与内存相关(==“非常讨厌”)的错误:

  • 如果您将该数组作为参数传递,那么您可以使用工厂方法没问题,因为保留/释放它是接受函数的责任
  • 如果您想继续使用该对象,请使用初始化方法并在最后释放该对象