先看如下代码
#import@interface Person : NSObject
@property (nonatomic, copy) NSString *cStr;
@property (nonatomic, strong) NSString *sStr;
@property (nonatomic, retain) NSString *rStr;
@end
@implementation Person
- (void)test {
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
self.cStr = mStr;
self.sStr = mStr;
self.rStr = mStr;
[mStr appendString:@"def"];
NSLog(@"%@", self.cStr);
NSLog(@"%@", self.sStr);
NSLog(@"%@", self.rStr);
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
Person *p = [[Person alloc]init];
[p test];
}
}
输出结果如下:
2016-04-08 10:12:14.255 Untitled[30829:303838] abc
2016-04-08 10:12:14.256 Untitled[30829:303838] abcdef
2016-04-08 10:12:14.256 Untitled[30829:303838] abcdef
用@property声明 NSString、NSArray、NSDictionary 经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。
copy此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为NSString时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。