这是一个有点愚蠢的问题,但是如果我想将一个对象添加到一个数组中,我可以使用NSMutableArray
和NSArray
来完成,我应该使用哪个?
NSMutableArray * array1;
[array1 addObject:obj];
NSArray * array2;
array2 = [array2 arrayByAddingObject:obj];
答案 0 :(得分:9)
NSMutableArray
不是线程安全的,而NSArray
是。{1}}。如果你是多线程的话,这可能是个大问题
NSMutableArray
和NSArray
都基于CFArray
构建,性能/复杂性应该相同。数组中值的访问时间保证为
任何实施,当前和未来的最差O(lg N),但会
通常是O(1)(恒定时间)。线性搜索操作类似
O(N * lg N)的最坏情况复杂,但通常是
边界会更紧,等等。插入或删除操作
通常在数组中的值的数量是线性的,但是
在某些实现中,在最坏的情况下,可能是O(N * lg N)。
答案 1 :(得分:8)
使用NSMutableArray,就是它的用途。如果我正在查看代码,我看到NSArray,我希望它的集合永远保持不变,而如果我看到NSMuteableArray,我知道该集合注定要改变。
现在听起来可能不是很多,但随着你的项目的发展和你花费更多时间,你最终会看到它的价值。
答案 2 :(得分:8)
在决定最佳使用时:
NSMutableArray
主要用于构建集合并且您想要修改它们。把它想象成动态。
NSArray
用于只读通知,并且:
你在这里做的是什么:
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和答案都很老,有人必须纠正它。
如果您在谈论性能,可以自己测量。但请记住Donald Knuth:“过早优化是所有邪恶的根源。”
从架构的角度来看,事情变得更加复杂。
首先我要提一下,拥有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.