天天看点

NSString 的copy和retain

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代码  

NSString 的copy和retain
  1. @interface Demo : NSObject  
  2. {  
  3.     NSString *retainString;  
  4.     NSString *copyString;  
  5. }  
  6. @property (nonatomic, retain)NSString *retainString;  
  7. @property (nonatomic, copy)NSString *copyString;  
  8. @end  
  9. @implementation Demo  
  10. @synthesize retainString;  
  11. @synthesize copyString;  
  12. -(void)dealloc  
  13. {  
  14.     [retainString release];  
  15.     [copyString release];  
  16.     [super dealloc];  
  17. }  
  18. @end  
  19. Demo *o = [[Demo alloc] init];  
  20. NSMutableString *s1 = [[NSMutableString alloc] initWithCapacity:100];  
  21. [s1 setString:@"changeme"];  
  22. o.retainString = s1;  
  23. o.copyString = s1;  
  24. NSLog(@"retain string is %@", o.retainString);  
  25. NSLog(@"copy string is %@", o.copyString);  
  26. [s1 setString:@"whetherchanged?"];  
  27. NSLog(@"retain string is %@", o.retainString);  
  28. 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