我应该在一个对象的属性中使用@property(nonatomic,copy)还是@property(nonatomic,strong)?

17
@interface PaneBean : NSObject

@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *type;
@property(nonatomic,assign) NSInteger width;
@end

如上所示,我有一个PaneBean。

对于我的(NSString *) name,我应该使用@property(nonatomic,copy)还是@property(nonatomic,strong)?它们之间有什么区别?

而对于NSInteger,写'assign'是正确的吗?

任何帮助将不胜感激。先谢谢了!


6
与答案无关,你可能需要考虑学习Cocoa的命名和设计规范。 "Bean" 是非常Java的术语,如果你与Cocoa程序员合作,他们可能不会理解它。 - Catfish_Man
哦,好的。我会编辑它。 - kongkong
@Catfish_Man 这一定是Java到ObjC翻译器"CocoaBeans"的输出 ;) - justin
1
可能是重复的问题:在ARC环境下,NSString属性应该是strong还是copy? - TalkLittle
4个回答

15

'copy'会导致属性的setter方法创建对象的一个副本,并且与'strong'没有任何区别。您可以使用它来确保如果有人将您的属性设置为可变字符串,然后修改该字符串,您仍然拥有原始值。如果该字符串不可变,Cocoa将默默地优化掉副本操作,这很好 :)

'strong'将保持属性的值在它被设置为其他值之前一直存在。如果您希望传入的可变字符串在您使用期间发生更改(这并非不可能,但也不是那么常见的事情),那么使用'strong'就是正确的选择。通常,'strong'更适用于表示比简单的“值”更复杂的对象(即不是NSString、NSNumber、NSValue等)。

'assign'是整数的默认(也是唯一可能的)设置。整数无法像对象一样被保留或复制。


由于分配是标量值的唯一可能设置,因此您永远不应明确指定它。苹果在文档中反复强调了这一点。我见过有经验的编码人员犯这个错误。 - SmileBot

7

对于类型为不可变值类且符合NSCopying协议的属性,您几乎总是应该在@property声明中指定copy。在这种情况下,指定retain几乎永远不是您想要的。在非ARC环境下,strong的作用与retain相同。

以下是原因:

NSMutableString *someName = [NSMutableString stringWithString:@"Chris"];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
[someName setString:@"Debajit"];

当前的Person.name属性值将根据该属性是否被声明为retain或copy而有所不同——如果该属性标记为retain,则其值为@"Debajit",但如果该属性标记为copy,则其值为@"Chris"。
由于在几乎所有情况下,您都希望防止在对象背后改变其属性,因此应将表示它们的属性标记为copy。(如果您自己编写setter而不是使用@synthesize,则应该记得在其中实际使用copy而不是retain。)

3

copy发送copy消息到您设置的对象,而strong仅保留它(增加引用计数)。

对于NSString或一般任何具有已知可变子类(NSArrayNSDictionatyNSSet)的不可变类,首选使用copy以避免客户端设置可变实例并在对象外进行修改。

对于原始类型(例如int),copy/strong没有意义,默认使用assign。是否要显式放置取决于您。


1

Strong表示组合,而Weak表示聚合。

复制意味着在将旧对象的内容复制到新对象之前需要创建一个新对象。在此情况下,拥有对象PaneBean将由新创建的对象组成。


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