何时使用retain和何时使用copy

时间:2010-11-03 12:53:20

标签: iphone objective-c

我对使用哪个以及何时使用感到困惑。有经验法则吗?大多数情况下可以使用它们吗?有什么特别规定吗?

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

在这种情况下哪个是最佳选择?

由于 -code

6 个答案:

答案 0 :(得分:14)

如果您不希望对象被另一个对象修改,您将需要使用副本。

一个很好的例子是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,则不会发生这种情况,因为您正在制作可变字符串的副本

答案 1 :(得分:9)

NSDate是不可变的,我们目前没有可变的子类。所以保留很好。复制也不会受到伤害,事实上我希望复制只是在这里交回相同的实例(再次保留)。

在NSString上使用 copy 的原因是你可能会将一个NSMutableString传递给你的对象,而这可能会在你的脚下发生变化。这不可能发生在这里。

答案 2 :(得分:3)

在iOS中,您通常使用单线程,因此您的对象不可能同时被修改。 此外,即使您指定copy,仍可以通过再次设置来修改该属性。

拇指规则是:“在iOS上使用retain

但是,很少有情况需要/建议使用副本:

  • 如果您接受阻止(使用iOS4添加的代码块) 必须使用副本,因为需要在保留之前将块复制到堆中(请参阅{{3} }了解更多详情
  • 如果您编写将在后台执行的代码,则使用起来更安全(原子,复制)。
  • 如果要确保仅分配给属性更改其值,则应考虑使用副本。 (如果你实施KVO可能会有用)

答案 3 :(得分:3)

经验法则是使用copy如果类实现NSCopying协议,除非你有充分的理由不这样做。我能想到的唯一理由就是表现。例如,从技术上讲,您应该将copy用于NSMutableArray属性,但是可以想象,复制大型可变数组会占用CPU时间和内存。“

答案 4 :(得分:1)

使用副本,您将拥有2个不同的对象。 因此,如果您修改一个,则不会修改另一个。

答案 5 :(得分:1)

复制为您提供单独的对象。

通常,您应该只使用retain,除非您明确要复制对象。每次复制都必须发布,所以请记住这一点。

使用-copy的好时机是当你要使用枚举添加或删除对象时。

例如,拿一个数组。如果要枚举数组,则在枚举期间无法向其添加或删除对象,否则您将崩溃。在开始枚举之前,使用-copy创建数组的新副本,并且在您枚举时,如果需要添加/删除对象(mutate),则可以在副本上执行此操作。

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