NSArray属性:copy还是retain?

22

根据这里的回答

对于 NSString/NSMutableString,建议使用 copy。

那么 NSArray/NSMutableArray 呢?

4个回答

27

既然您询问的是NSArray(而不是NSMutableArray),那么您应该使用copy。NSArray是不可变的,所以您不希望该类型的属性发生更改。但是NSMutableArray是NSArray的子类,因此可以合法地传递NSMutableArray。如果您只保留该对象,那么它可能会在您眼前发生更改。如果您使用copy而不是retain,则该对象将不会更改。

然而,您应该知道当您复制像NSArray这样的容器时,您只复制了容器本身而不是其中的内容。如果数组包含可变对象,那么即使数组本身是不可变的,这些对象的内容也可能会更改。


@Caleb 那么 @property(copy) NSArray *myArray 的唯一优势就是防止数组大小改变吗?它不能防止淘气的人传入一个 NSMutableArray 并更改其内容。 - Pwner
@Pwner @property(copy) 会防止数组的内容发生变化,也就是说数组将继续引用相同顺序的对象,但它不能防止单个对象本身被更改。 - Caleb

19

选择copy,除非你有非常特殊的理由不这样做,并且需要支持相应的代码/接口。

我在这里详细说明了原因和一些影响: NSMutableString作为retain/copy

该示例基于NSString,但同样适用于NSArray


9

如果底层数据发生变化会有问题,那么请使用 copy。实际上,大多数情况下这是您想要的,因为在某人背后更改数据是错误的好源头。

请注意,对于NSArray,copy本质上只是一个retain。只有当你使用NSMutableArray时,才需要更多的工作。


5
从您提供的链接中,可以总结出以下内容:NSString属性:copy还是retain? 如果您想确保对象的值在执行期间不会更改,则使用“copy”属性,否则“retain”也可以。通常,“retain”对于NSMutableArraysNSArrays(以及许多其他对象)都可以使用,因为您(通常)更感兴趣的是对象而不是它所包含的值。在NSString的情况下,您始终对值感兴趣,因此将其copy以确保它不会更改。 @jlehr: 这取决于开发人员是否真正关心实际值。每当您关心实际值时,请使用copy(因为您不希望在执行期间更改值),否则retain就可以了。来自Apple文档的信息:

在Objective-C代码中,复制值对象(表示属性的对象)是一种常见做法。C类型变量通常可以替换为值对象,但值对象具有封装方便的实用程序以进行常见操作的优点。例如,使用NSString对象代替字符指针,因为它们封装了编码和存储。

另外,来自Apple文档的信息,关于值对象:

价值对象本质上是一个面向对象的简单数据元素的包装器,例如字符串,数字或日期。 Cocoa中常见的值类是NSString,NSDate和NSNumber。值对象通常是您创建的其他自定义对象的属性。


1
在两个或多个对象之间共享可变集合的内容会违反封装性,这就是为什么苹果建议对类型为NSArray的属性使用“复制”语义的原因。 - jlehr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接