NSMutableArray -init vs. + arrayWithCapacity:

时间:2009-11-13 17:22:27

标签: iphone objective-c

我有两个功能,我应该使用哪一个? 请解释一下差异。

A:

- (NSMutableArray *)FunctionA:(int)count {

    NSMutableArray *a = [[NSMutableArray alloc] init];

 for (int i = 0; i < count; i++) {
  [a addObject:[NSNumber numberWithInt:0] ];
    }

    return [a autorelease];
}

B:

-(NSMutableArray *)FunctionB:(int)count {

 NSMutableArray *b = [NSMutableArray arrayWithCapacity:count];

 for (int i=0;i<count; i++){  
  [b addObject:[NSNumber numberWithInt:0] ];  
 }

 return b;  //  or [b autorelease] ?
}

4 个答案:

答案 0 :(得分:28)

第一个创建可变数组而不指定容量。这会导致在添加项目时数组必须增长。在内部,这可能经过大量优化,一次发生“块”,但是在添加项目时仍然需要增加数组并分配更多空间。

第二个给数组一个提示(你可能需要“这么多”的空间)以避免在添加已知数量的对象时增加数组的开销。当然,如果需要,它仍然会变大(就像你没有指定容量一样)。如果您已经提前了解计数,则应使用此方法。大量计数会更快。

如果您在优化之前没有进行测量,那么这有一个缺点:但是:如果您正在创建一个具有非常高容量但不总是使用该容量的可变阵列,则会产生分配所有空间的代价。

另外,你没有自动释放B(因为你注释掉了),因为你没有用init创建可变数组 - 你使用了一个方便的方法,它自己做了,这意味着你不负责释放它。正如我在对你的问题的另一个答案的评论中提到的那样,你也可以用:

创建数组

[[NSMutableArray alloc] initWithCapacity:capacity];

...然后在准备好后释放它。与使用自动释放池相比,这使您可以更好地控制内存使用,这是iPhone平台上的一个重要考虑因素。

请记住:先测量,然后根据需要进行优化。

答案 1 :(得分:1)

可变对象仍需要分配空间,以便为10个对象分配默认数量。如果添加第11个,则可变数组将必须分配新内存,将项目复制到新内存,并释放旧内存。

这通常是如此之快,你甚至都不会注意到,但它可能会减慢速度。创建具有大小的可变数组最初会创建指定大小的数组,因此希望减少调整大小。

答案 2 :(得分:1)

在第一个示例中,您必须管理数组的内存,因为您使用+alloc-init创建它(这就是您需要向其发送-autorelease的原因)。

在第二个示例中,您不必管理数组的内存,因为它会自动释放返回给您(因为您使用便捷方法创建了它)。此外,由于您预先指定了所需的阵列大小,因此可能更有效。

如果你想返回一个自动释放的数组,那么第二个选项可能更可取,因为+arrayWithCapacity:将返回一个已经自动释放的数组。此外,由于返回给您的阵列已经自动释放,您不必自己发送-autorelease

如果您对内存管理有任何疑虑,那么必须阅读Apple Memory Management Guidelines

答案 3 :(得分:0)

我用B:

我看到它的优点是

  • 当数组变大时,数组不需要调整大小
  • arrayWithCapacity:自动释放给你,所以你没必要,这提高了代码的可读性imho

我希望有所帮助。