NSMutableArray的arrayWithCapacity与initWithCapacity区别

6

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

我正在学习Objective-C中的内存管理,并阅读苹果公司的内存管理文档:http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

在对象所有权策略部分,它说您拥有通过以alloc、new或包含copy开头的方法创建的任何对象。所有权意味着您需要在使用完对象后显式释放它。

因此,我正在查看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个回答

9

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

当您知道自己将拥有创建的对象时,alloc/init调用始终比方便/保留方式更有效,因为后者需要基本上对对象进行alloc/init/autorelease,然后在返回时保留它。

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


现在我们有自动引用计数,这个说法还正确吗?在我看来,由于ARC代码现在基本上将隐式autorelease应用于alloc/init创建的对象,所以这两种方法现在必须非常相似。如果我理解正确的话,大多数情况下我们应该使用方便的方法(如果存在)以获得简单和清晰,因为现在没有任何性能惩罚。 - Mike

6

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

initWithCapacity:需要显式地保留,您需要自己释放它。由于通常将其调用为[[A alloc] init...],这将触发一个灯泡“我需要管理此内存”的提示,除了“alloc”之外的其他类似魔术词还有“new”和“copy”,正如您在内存管理指南中所读到的那样。但从您的问题来看,似乎您很好地理解了其原则。

您正确地认为应该管理并降低内存占用,但这并不意味着您必须始终进行显式的init/release操作。正如Nick所说,使用自动释放工厂方法的一种用例是在将它们作为参数传递时。

另一个例子是当您向NSDictionary或NSArray等集合添加某些内容时,“something”可以使用自动释放工厂方法创建,因为集合“接管”了它的保留。(将东西添加到集合时保留,删除时释放。)

您可能会争辩说

Blah *blah = [Blah blahWithSomething];
[myMutableArray addObject:blah];

相对于

来说,只是更易于输入。

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

在第一种情况下,您根本不需要担心释放调用。缺点是,如果在同一个runloop中多次执行此操作,并且它是一个在runloop结束时消失的临时/可抛弃的数组对象,则第一种情况的内存占用量更大。但是,如果它是一个小对象,不是在循环中完成并且保留时间较长,这是常见的情况,它们的占用空间相同。

0
在这种情况下,我尝试遵循以下规则以避免与内存相关的(==“非常讨厌”)错误:
  • 如果您将该数组作为参数传递,则可以毫不费力地使用工厂方法,因为接受函数有责任保留/释放它
  • 如果您想继续使用对象,请使用初始化方法并在结束时释放对象

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接