何时使用 retain 和何时使用 copy

15

我对何时使用哪个很困惑。有什么经验法则吗?在大多数情况下,两者都可以使用吗?是否有特殊规则?

@property (nonatomic, retain) NSDate *theDateFromPicker;
@property (nonatomic, copy) NSDate *theDateFromPicker;

在这种情况下哪种选择最好?

谢谢 -Code

6个回答

14

当您不希望对象被另一个对象修改的可能性时,应使用copy。

一个很好的例子是NSString。假设你有这段代码:

@property (nonatomic, retain) NSString *aString;

// in some other class

NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@"test"];
theObject.aString = mutableString; // theObject retains the mutable string

[mutableString setString:@"test2"];

这里发生的情况是把值 "test" 赋给了 aString,但它随后被外部修改为了 "test2",因为你对可变字符串进行了保留。如果你使用了copy,那么这种情况就不会发生,因为你正在制作一个副本可变字符串。


10

NSDate是不可变的,我们目前没有可变的子类。所以保留原对象是可以的。复制也不会有问题,而且我认为复制只是再次返回同一个实例(再次被保留)。

在NSString中使用复制的原因是,你可能会收到一个NSMutableString作为参数传递给你的对象,而这个字符串可能会在你操作时被修改。但是在这里不可能发生这种情况。


3
在iOS中,通常您会使用单线程,因此不存在对象同时被修改的可能性。此外,即使您指定了copy,该属性仍然可以通过再次设置来进行修改。
经验法则是:"在iOS上使用retain"
但是在以下情况下需要/建议使用copy:
- 如果您接受代码块(在iOS4中添加的代码块)作为参数,则必须使用copy,因为代码块需要先复制到堆中,然后再进行保留(有关更多详细信息,请参见Objective-C中复制块(即将它们复制到实例变量中)) - 如果您编写将在后台执行的代码,则更安全的方法是使用(atomic,copy)。 - 如果您想确保只有分配给属性才会更改其值,则应考虑使用copy(如果您实现KVO,则可能很有用)。

3

经验法则是如果类实现了NSCopying协议,使用copy,除非你有充分的理由不这样做。我唯一能想到的好理由是性能问题。例如,技术上应该使用copy来处理NSMutableArray属性,但你可以想象,复制大型可变数组将消耗大量的CPU时间和内存。


1

使用复制操作,你将会得到两个不同的对象。 因此,如果你修改其中一个对象,另一个对象不会被修改。


1

Copy 方法能生成一个独立的对象。

通常情况下,您应该只使用 retain,除非您明确想要复制对象。每次复制都必须释放(release),所以请记住这一点。

当您需要使用枚举来添加或删除对象时,可以使用 -copy 方法。

比如说,如果您正在枚举一个数组,那么在枚举期间不能向其中添加或删除对象,否则会导致程序崩溃。在开始枚举之前,使用 -copy 创建数组的副本,在枚举时,如果需要添加/删除对象(更改),可以在副本上进行操作。

当您完成枚举后,可以将副本设置回原始状态。


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