stackoverflow上的说法是这样的。http://stackoverflow.com/questions/387959/nsstring-property-copy-or-retain
For attributes whose type is an immutable value class that conforms to the
NSCopying
protocol, you almost always should specify
copy
in your
@property
declaration. Specifying
retain
is something you almost never want in such a situation.
Here's why you want to do that:
NSMutableString *someName = [NSMutableString stringWithString:@"Chris"];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
[someName setString:@"Debajit"];
The current value of the
Person.name
property will be different depending on whether the property is declared
retain
or
copy
— it will be
@"Debajit"
if the property is marked
retain
, but
@"Chris"
if the property is marked
copy
.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them
copy
. (And if you write the setter yourself instead of using
@synthesize
you should remember to actually use
copy
instead of
retain
in it.)
规范上NSString做属性都是写成copy的,理论上应该是复制了字符串而不是单纯的增加引用计数,
其实问题只会出现在把NSMutableString赋值给NSString的时候。如果对实际类型就是NSString的对象用了copy,那其实就是retain,你可以通过观察引用计数来发现,而且就语义上来说也完全没有问题,同时也避免了不需要的字符串拷贝的消耗
Objective-c代码
- @interface Demo : NSObject
- {
- NSString *retainString;
- NSString *copyString;
- }
- @property (nonatomic, retain)NSString *retainString;
- @property (nonatomic, copy)NSString *copyString;
- @end
- @implementation Demo
- @synthesize retainString;
- @synthesize copyString;
- -(void)dealloc
- {
- [retainString release];
- [copyString release];
- [super dealloc];
- }
- @end
- Demo *o = [[Demo alloc] init];
- NSMutableString *s1 = [[NSMutableString alloc] initWithCapacity:100];
- [s1 setString:@"changeme"];
- o.retainString = s1;
- o.copyString = s1;
- NSLog(@"retain string is %@", o.retainString);
- NSLog(@"copy string is %@", o.copyString);
- [s1 setString:@"whetherchanged?"];
- NSLog(@"retain string is %@", o.retainString);
- NSLog(@"copy string is %@", o.copyString);
这样就可以看出,当使用retain方式的时候,NSMutableString的内容变化时,语义上应该不可变的NSString也变化了,而用copy则是始终保持赋值时的内容。
1。对NSString应用retain,效率无疑是最好的
2。用copy最安全,因为NSString 为 NSMutableString 的基类,如果将NSMutableString 以retain的形式赋值给NSString后,后续修改NSMutableString会导致NSString内容的变化,这通常不是我们希望的,所以用copy最安全。
3。到底用哪个?貌似还是用copy,因为copy并不一定导致一个新对对象创建,而牺牲效率。copy会调用NSCopying中的 -(id)copyWithZone:(NSZone *),我们可以判断下self是NSString还是NSMutableString,如果是NSString,就地[self retain],[return self]。否则老老实实拷贝对象赋值,这样可以实现效率和安全的结合,实验的结果也是如此。
from:http://bukkake.iteye.com/blog/954259