我对使用哪个以及何时使用感到困惑。有经验法则吗?大多数情况下可以使用它们吗?有什么特别规定吗?
@property (nonatomic, retain) NSDate *theDateFromPicker;
@property (nonatomic, copy) NSDate *theDateFromPicker;
在这种情况下哪个是最佳选择?
由于 -code
答案 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
”
但是,很少有情况需要/建议使用副本:
答案 3 :(得分:3)
经验法则是使用copy
如果类实现NSCopying
协议,除非你有充分的理由不这样做。我能想到的唯一理由就是表现。例如,从技术上讲,您应该将copy
用于NSMutableArray
属性,但是可以想象,复制大型可变数组会占用CPU时间和内存。“
答案 4 :(得分:1)
使用副本,您将拥有2个不同的对象。 因此,如果您修改一个,则不会修改另一个。
答案 5 :(得分:1)
复制为您提供单独的对象。
通常,您应该只使用retain,除非您明确要复制对象。每次复制都必须发布,所以请记住这一点。
使用-copy的好时机是当你要使用枚举添加或删除对象时。
例如,拿一个数组。如果要枚举数组,则在枚举期间无法向其添加或删除对象,否则您将崩溃。在开始枚举之前,使用-copy创建数组的新副本,并且在您枚举时,如果需要添加/删除对象(mutate),则可以在副本上执行此操作。完成枚举后,您可以将副本设置回原始版本。