我们通过实际操作来说明,我们把str赋值给zhangsan的name属性,然后去改变str,结果:
用@property (nonatomic, retain) NSString *name;
修饰的name答应结果为zhangsanabc
,name
属性被修改了;
用@property (nonatomic, copy) NSString *name;
修饰的name答应结果为zhangsan
,name
属性没有被修改。
NSMutableString *str = [NSMutableString string];
str.string = @"zhangsan";
Person *zhangsan = [[[Person alloc] init] autorelease];
zhangsan.name = str;
[str appendString:@"abc"];
NSLog(@"%@ %@", str, zhangsan.name);
下面我们来看代码set方法的内部实现:
当.h用@property (nonatomic, retain) NSString *name;
时,_name = [name retain];
相当于[name retain]; 和 _name = name;
,而这两句话相当于是先把原来的作引用计数+1,再把指针付给_name,实际上指向的是一块内存,这样会导致原来的内容改变,_name也会改变,而实际中我们一般不希望_name改变,所以我们不用retain。
- (void)setName:(NSString *)name {
if (_name != name) {
[_name release];
_name = [name retain];
//_name = [name retain];相当于下边两句,而这两句话相当于是先把原来的作引用计数+1,再把指针付给_name,实际上指向的是一块内存,这样会导致原来的内容改变,_name也会改变,而实际中我们一般不希望_name改变,所以我们不用retain
// [name retain];
// _name = name;
}
}
- (void)dealloc {
// [_name release];
// _name = nil;
self.name = nil;
[super dealloc];
}
当.h用@property (nonatomic, copy) NSString *name;
时,当传入的值为可变对象时,调用_name = [name copy];
copy会创建一个新的对象赋值给_name,所以_name和name是两块无关的内容,改变name不会影响_name
- (void)setName:(NSString *)name {
if (_name != name) {
[_name release];
// 当传入的值为可变对象时,copy会创建一个新的对象赋值给_name,所以_name和name是两块无关的内容,改变name不会影响_name
_name = [name copy];
}
}
- (void)dealloc {
// [_name release];
// _name = nil;
self.name = nil;
[super dealloc];
}
网友评论