NSMutableArray vs NSArray哪个更好

时间:2011-11-21 04:44:29

标签: objective-c

这是一个有点愚蠢的问题,但是如果我想将一个对象添加到一个数组中,我可以使用NSMutableArrayNSArray来完成,我应该使用哪个?

NSMutableArray * array1;
[array1 addObject:obj];
NSArray * array2;
array2 = [array2 arrayByAddingObject:obj];

6 个答案:

答案 0 :(得分:9)

NSMutableArray不是线程安全的,而NSArray是。{1}}。如果你是多线程的话,这可能是个大问题 NSMutableArrayNSArray都基于CFArray构建,性能/复杂性应该相同。数组中值的访问时间保证为     任何实施,当前和未来的最差O(lg N),但会     通常是O(1)(恒定时间)。线性搜索操作类似     O(N * lg N)的最坏情况复杂,但通常是     边界会更紧,等等。插入或删除操作     通常在数组中的值的数量是线性的,但是     在某些实现中,在最坏的情况下,可能是O(N * lg N)。

答案 1 :(得分:8)

使用NSMutableArray,就是它的用途。如果我正在查看代码,我看到NSArray,我希望它的集合永远保持不变,而如果我看到NSMuteableArray,我知道该集合注定要改变。

现在听起来可能不是很多,但随着你的项目的发展和你花费更多时间,你最终会看到它的价值。

答案 2 :(得分:8)

在决定最佳使用时:

NSMutableArray主要用于构建集合并且您想要修改它们。把它想象成动态。

NSArray用于只读通知,并且:

  • 用于填充NSMutableArray,以执行修改
  • 用于临时存储不需要编辑的数据

你在这里做的是什么:

NSArray * array2;
array2 = [array2 arrayByAddingObject:obj];

您是在创建新的NSArray并将指针更改为您创建的新阵列的位置。

您正在以这种方式泄漏内存,因为在添加新对象之前它没有清理旧数组。

如果您仍想要这样做,您需要清理如下:

NSArray *oldArray;
NSArray *newArray;
newArray = [oldArray arrayByAddingObject:obj];
[oldArray release];

但最佳做法是执行以下操作:

NSMutableArray *mutableArray;
// Initialisation etc
[mutableArray addObject:obj];

答案 3 :(得分:1)

即使Q和答案都很老,有人必须纠正它。

  1. “更好”是什么意思?哪个更好?你的Q泄漏信息是什么问题,它是高度意见的。但是,它没有关闭。
  2. 如果您在谈论性能,可以自己测量。但请记住Donald Knuth:“过早优化是所有邪恶的根源。”

    1. 如果我认真对待你的Q,“更好”可能意味着运行时性能,内存占用或架构。对于前两个主题,很容易检查自己。所以不需要回答。
    2. 从架构的角度来看,事情变得更加复杂。

      首先我要提一下,拥有NSArray的实例并不意味着它是不可变的。这是因为在Cocoa中,集合的可变变体是不可变变体的子类。因此,NSMutableArray 的实例NSArray的实例,但显然是可变的。

      可以说这不是一个好主意,尤其是在考虑Barbara and Jeanette并且与circle-ellipse problem有关系时,这并不容易解决。但是,它确实如此。

      因此,只有文档可以为您提供信息,返回的实例是否是不可变的。或者您进行运行时检查。出于这个原因,有些人总是对每个可变集合进行-copy

      然而,可变性是万恶之源。因此:如果可能,请始终创建NSArray的实例作为最终结果。如果你从一个方法(特别是getter)返回那个实例,那么在你的文档中写下它,这样每个人都可以依赖不变性。这可以防止“幕后”发生意外更改。 很重要,不是0.000000000003秒运行时或130字节内存。

答案 4 :(得分:1)

NSArray 对象管理一个不可变的数组,也就是说,创建数组后,就无法添加,删除或替换对象。但是,您可以自己修改单个元素(如果它们支持修改)。集合的可变性不影响集合内对象的可变性。如果数组很少更改或大量更改,则应使用不可变数组。

NSMutableArray 对象管理一个可变数组,该数组允许添加和删除条目,并根据需要分配内存。例如,给定一个仅包含单个dog对象的NSMutableArray对象,您可以添加另一只dog或cat或任何其他对象。您也可以像使用NSArray对象一样更改狗的名字,并且通常来说,使用NSArray对象可以执行的任何操作都可以使用NSMutableArray对象来进行。如果数组的增量更改或更改非常大,则应使用可变数组-因为大型集合需要更多时间来初始化。

答案 5 :(得分:-1)

此测试给出了最佳答案:

方法1:

NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
NSMutableArray *mutableItems = [[NSMutableArray alloc] initWithCapacity:1000];
for (int i = 0; i < 10000; i++) {
    [mutableItems addObject:[NSDate date]];
}
NSTimeInterval  end = [NSDate timeIntervalSinceReferenceDate];
NSLog(@"elapsed time = %g", (end - start) * 1000.0);

方法2:

...
NSArray *items = [[[NSArray alloc] init] autorelease];
or (int i = 0; i < 10000; i++) {
    items = [items arrayByAddingObject:[NSDate date]];
}
...

输出:

Method 1: elapsed time = 0.011135 seconds.    
Method 2: elapsed time = 9.712520 seconds.