#import "ViewController.h"
@interface ViewController ()
@property (retain,nonatomic) NSString *rStr; //这里的retain和strong是一样的
@property (copy, nonatomic) NSString *cStr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
}
- (void)test
{
NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
self.rStr = mStr; //retain的方式就是引用赋值
self.cStr = mStr; //cop有的方式就是深拷贝
NSLog(@"mStr:%16p,%16p,%16@", mStr,&mStr,mStr);
NSLog(@"retainStr:%16p,%16p,%16@", _rStr, &_rStr,_rStr);
NSLog(@"copyStr:%16p,%16p,%16@", _cStr, &_cStr,_cStr);
[mStr appendString:@"de"];
NSLog(@"mStr:%16p,%16p,%16@", mStr,&mStr,mStr);
NSLog(@"retainStr:%16p,%16p,%16@", _rStr, &_rStr,_rStr);
NSLog(@"copyStr:%16p,%16p,%16@", _cStr, &_cStr,_cStr);
}
@end
运行之后的结果是:
从上面结果我们可以看出:
假如,mStr对象的地址为0x7ff3ea505f00,也就是0x11是@“abc”的首地址,mStr变量自身在内存中的地址为0x7fff59bd9b08;(这里注意对象的地址和自身变量的地址)
当把mStr赋值给retain的rStr时,rStr对象的地址为0x7ff3ea505f00,rStr变量自身在内存中的地址为0x7ff3ea7366d8;rStr与mStr指向同样的地址,他们指向的是同一个对象@“abc”,这个对象的地址为0x7ff3ea505f00,所以他们的值是一样的。(注意:他们自身的变量的地址是不同的)
当把mStr赋值给copy的cStr时,cStr对象的地址为0x7ff3ea50b580,cStr变量自身在内存中的地址0x7ff3ea7366e0;cStr与mStr指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0x7ff3ea50b580,值为@“abc”。(也就是赋值出来一份)
同时看到增加了字符串了之后,retain中的值也会修改,而copy中的值不会修改,所以我们定义这些基础的变量,我们一般都是使用copy来定义。
拓展:
NSObject自带的常用的对象有:NSNumber、NSString、NSArray、NSDictionary、NSMutableArray、NSMutableDictionay、NSMutableString,copy产生的对象时不可变的,mutableCopy产生的对象时可变的。
也就是上面的这些类,如果定义一个对象的时候,我们将会使用的是copy或者mutableCopy来定义。