返回mutable与返回的不可变(非成员)对象

时间:2011-06-13 13:55:33

标签: objective-c cocoa nsmutablearray

我几乎没有看到第二个用过,我想知道为什么?

  • 对于需要NSArray的情况(因为它是子类),不会破坏支持
  • 通过揭示可变的内部结构也不会打破封装

在前提条件下,它永远不会是一个可变的ivar, (无论如何应该是常识)
我现在只能想到使用第二个的优点。

  • 实际上可变的。这里静音安全,所以为什么要阻止
  • 无需拨打[[[foo fooBar] mutableCopy] autorelease]不必要地分配额外内存不必要地浪费时间

以下是方法变体:

- (NSArray *)fooBar {
    NSMutableArray *fooArray = [NSMutableArray array];
    //populate fooArray
    return fooArray;
}

- (NSMutableArray *)fooBar {
    NSMutableArray *fooArray = [NSMutableArray array];
    //populate fooArray
    return fooArray;
}

我问我的项目有一堆具有相同模式的方法 并且在大多数时,返回的数组将在之后被修改(合并,编辑等)。
所以我认为应该完全正常才能返回NSMutableArrays,但似乎没有人这样做

NSMutableArrayNSMutableSetNSMutableDictionary ......这基本上是相同的交易。

3 个答案:

答案 0 :(得分:4)

有关使用mutable与immutable的解释,请查看Apple Object Mutability上的文档。

通常,最好返回一个不可变版本,除非特别指出返回的对象始终是一个可供任何客户端更改的不可变对象。您应该根据接口的意图创建接口,而不是根据当前实现。需求可能会发生变化,您需要更改fooBar的实现,以便返回实例变量。通过返回可变数组,您可以确保不仅封装实例变量,还封装当前实现。

所以,你可能有一个有效的位置来返回一个可变数组(我不知道),但你看到大多数代码传递不可变数组,因为它完全封装了它们的变量及其实现。

答案 1 :(得分:2)

我认为第一种变异是首选,因为多态性是首选。

在任何一种情况下,两种方法都返回NSMutableArray的实例,唯一的区别是第一个实例隐藏了来自调用者的事实。换句话说,第一个变体比第二个更安全。它主要使用多态来告诉调用者可能返回任何类型的NSArray。如果您需要在代码中具有这种灵活性,那么它肯定具有优势。 (例如,如果有一天,无论出于何种原因,您需要返回一个自定义NSArray子类,您的代码将不会在该级别中断)。

但是,您似乎更喜欢将意图传递给调用者 - 即您实际返回可变数组 - 这也没关系。为了让每个人都开心(如果有这样的事情......),我建议将第二种方法重命名为:

- (NSMutableArray *)mutableFooBar {
    NSMutableArray *fooArray = [NSMutableArray array];
    //populate fooArray
    return fooArray;
}

作为旁注,我认为以下是将现有的不可变数组转换为可变数组的稍微有效的方法:

NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:fooArray];

(如果我在这个假设上错了,请纠正我。)

我希望这能回答你的问题...

答案 2 :(得分:0)

让方法返回一个看起来可疑的可变实例。

作为调用者,您必须质疑原始方法签名,并想知​​道改变返回值是否真的是安全的。在所有类可能无意中返回指向内部状态的指针之后。

如果分析显示此副本确实很昂贵,我通常会更改方法签名,以明确表明可变性是有意的。也许有类似的东西:

- (void)populateFooBars:(NSMutableArray *)array;

很明显,结果的可变性是有意的。