【问题标题】:NSMutableArray vs NSArray which is betterNSMutableArray vs NSArray 哪个更好
【发布时间】:2011-11-21 04:44:28
【问题描述】:

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

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

【问题讨论】:

  • 在这两种情况下,您的数组都是nil,因为对象永远不会被初始化。你需要类似:NSMutableArray *array1 = [NSMutableArray array];

标签: objective-c


【解决方案1】:

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

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

【讨论】:

  • 由于NSMutableArrayNSArray 的子类,你不能做出这样的假设。这是 Cocoa 中的设计失败,但就是这样。确保不变性的唯一方法是进行复制。 (也许这是在数花生……)
【解决方案2】:

NSMutableArray 不是线程安全的,而NSArray 是。如果您使用多线程,这可能是一个大问题。
NSMutableArrayNSArray 都基于 CFArray,性能/复杂性应该相同。保证数组中值的访问时间为 对于当前和未来的任何实现,最差的 O(lg N),但会 通常是 O(1)(恒定时间)。类似的线性搜索操作 具有 O(N*lg N) 的最坏情况复杂度,尽管通常 界限会更紧,依此类推。插入或删除操作 通常在数组中的值数量上是线性的,但是 在某些实现中,在最坏的情况下显然可能是 O(N*lg N)。

【讨论】:

  • 您在哪里阅读过关于目标 C 中数据结构性能的信息?
【解决方案3】:

在决定哪个最好使用时:

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];

【讨论】:

    【解决方案4】:

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

    NSMutableArray 对象管理一个可变数组,允许添加和删除条目,根据需要分配内存。例如,给定一个只包含一个狗对象的 NSMutableArray 对象,您可以添加另一条狗、一只猫或任何其他对象。你也可以像使用 NSArray 对象一样,更改狗的名字——一般来说,你可以用 NSArray 对象做的任何事情都可以用 NSMutableArray 对象做。如果数组以增量方式更改或非常大,则应使用可变数组 - 因为大型集合需要更多时间来初始化。

    【讨论】:

      【解决方案5】:

      连Q和答案都太老了,总得有人改正。

      1. “更好”是什么意思?更好的是什么?您的 Q 泄露信息是什么问题,并且是高度基于意见的。但是,它并没有关闭。

      如果您谈论的是性能,您可以自己衡量。但请记住 Donald Knuth:“过早的优化是万恶之源”。

      1. 如果我认真对待您的 Q,“更好”可能意味着运行时性能、内存占用或架构。对于前两个主题,很容易检查自己。所以不需要回答。

      从架构的角度来看,事情变得更加复杂。

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

      可以说这不是一个好主意,尤其是考虑到Barbara and Jeanette 并且与circle-ellipse problem 有关系,这不容易解决。然而,事情就是这样。

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

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

      【讨论】:

        【解决方案6】:

        这个测试给出了最好的答案:

        方法一:

        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);
        

        方法二:

        ...
        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.
        

        【讨论】:

        • 哪个问题的最佳答案?
        • 对于标题中的 Q:“NSMutableArray 与 NSArray 哪个更好?”
        • 最擅长什么主题?内存占用?运行时性能?建筑?最快 = 最好是完全错误的,而且在当今大多数应用程序中,性能毫无意义。通常不可变是“最好的”,因为可变性很难处理。
        • 如果对你来说“性能毫无意义”和“可变性难以处理”——我没有 cmets。
        • 当然。您没有软件开发经验。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-16
        • 2015-11-09
        • 2010-11-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-30
        相关资源
        最近更新 更多