有没有理由不返回一个不可预期的可变对象?

tit*_*coy 7 objective-c

我有许多类似于以下的功能:

+ (NSArray *)arrayOfSomething
{
    NSMutableArray *array = [NSMutableArray array];

    // Add objects to the array

    return [[array copy] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

我的问题是关于这个方法的最后一行:返回可变对象并避免复制操作或返回不可变副本是否更好?是否有任何充分的理由避免返回一个不可预期的可变对象?

(我知道返回NSMutableArray是合法的,因为它是NSArray的子​​类.我的问题是这是否是一个好主意.)

Jer*_*myP 4

这是一个复杂的话题。我认为最好让您参考 Apple 关于对象可变性的指南。

\n\n

关于使用内省来确定返回对象的可变性,Apple 有这样的说法:

\n\n
\n

为了确定是否可以更改接收到的对象,接收者必须依赖返回值的形式类型。例如,如果它接收到一个类型为不可变的数组对象,则它不应该尝试改变它。根据对象的类成员身份确定对象是否可变不是可接受的编程实践

\n
\n\n

(我的重点)

\n\n

本文继续给出了几个很好的理由,说明为什么您不应该对返回的对象使用内省来确定是否可以改变它,例如

\n\n
\n

您从文件中读取属性列表。当 Foundation 框架处理该列表时,它注意到属性列表的各个子集是相同的,因此它创建了一组在所有这些子集中共享的对象。然后,您查看创建的属性列表对象并决定更改一个子集。突然间,您\xe2\x80\x99 在不知不觉中在多个位置更改了树。

\n
\n\n

\n\n
\n

您向 NSView 询问其子视图(subviews 方法),它返回一个声明为 NSArray 但内部可能是 NSMutableArray 的对象。然后,将该数组传递给其他一些代码,这些代码通过内省确定它是可变的并更改它。通过更改此数组,代码正在改变 NSView\xe2\x80\x99s 内部数据结构。

\n
\n\n

鉴于上述情况,您在示例中返回可变数组是完全可以接受的(当然,前提是您在返回它后永远不会自己对其进行更改,因为那样您就会违反合同)。

\n\n

话虽如此,几乎没有人读过《Cocoa 对象指南》的这一部分,因此防御性编程会要求您制作一个不可变的副本并返回该副本,除非性能分析表明这样做是有问题的。

\n