什么是copy?
顾名思义,就是拷贝,拷贝视频,拷贝txt,在window下面就是复制,就是生成一个副本文件,和源文件内容一模一样.
字符串的Copy/MutableCopy方法
>可变字符串(可以被修改)的copy.
1.假设NSMutableString通过copy之后产生的对象是可变的.
NSMutableString *str = [NSMutableString stringWithFormat:@"张三"]; NSMutableString *str2 = [str copy]; [str2 appendString:@"与李四"]; NSLog(@"%@",str2);
NSLog(@"%p----%p",str,str2);0x7fb56a470b10----0x7fb56a439af0//副本对象重新分配了内存
报错:
reason: 'Attempt to mutate immutable object with appendString:'
>不可变字符串(不可以被修改)的copy.
1.假设不可变字符串copy后产生的对象是可变的,那么可以用NSMutableString接收,并拼接字符串,
NSString *STR = @"小鱼儿"; NSMutableString *STR2 = [STR copy]; [STR2 appendString:@"与花无缺"]; NSLog(@"%@",STR2);
NSLog(@"%p----%p",str,str2); 0x10bbd3068----0x10bbd3068//并没有产生副本对象.
然而,报错了.
reason: 'Attempt to mutate immutable object with appendString:'
说明---NSString通过copy产生的是不可变对象,只能用NSString接收,也是不可变字符串
综上:不论是可变字符串还是不可变字符串,只要是通过copy方式产生副本对象,这个副本对象都是不可以改变的.
>字符串的MutableCopy,
>可变字符串的MutableCopy.
>1.假设产生的副本对象是是不可变的
NSMutableString *str = [NSMutableString stringWithFormat:@"志明"]; NSMutableString *str2 = [str mutableCopy]; [str2 appendString:@"与春娇"]; NSLog(@"%@",str2);
NSLog(@"%p----%p",str,str2); //0x7fdbf948b080----0x7fdbf948b100
输出:志明与春娇
说明----可变字符串通过MutableCopy产生的对象是可变的./副本对象重新分配了内存
>不可变字符串的MutableCopy.
>2.假设产生的副本对象是不可变的
NSString *str = @"美女"; NSMutableString *str2 = [str mutableCopy]; [str2 appendString:@"与野兽"]; NSLog(@"%@",str2);
NSLog(@"%p----%p",str,str2);//输出0x10b5bb068----0x7f8392527e80
输出:美女与野兽
说明----不可变字符串通过MutableCopy产生的副本对象是可变的.
综上,只要是通过MutableCopy产生副本对象,不管原对象是否可变,副本对象都是可变的./副本对象重新分配了内存
注意:NSString通过copy并没有产生新对象,只是指针(地址)的拷贝.就是说是并没有真正产生副本对象.
copy与内存管理
NSString通过copy方式产生的副本对象只是对象地址的拷贝.
NSString *str = [NSString stringWithFormat:@"中"]; NSLog(@"str.retainCount = %lu",str.retainCount);//1 NSString *str2 = [str copy]; NSLog(@"str = %p----str2 = %p",str,str2);//一样 NSLog(@"str.retainCount = %lu",str.retainCount);//2 NSLog(@"str2.retainCount = %lu",str2.retainCount);//2
NSMutableString通过copy方式产生了真正的副本对象.
有一个person类,有一个name属性
@property (nonatomic,strong) NSString *name;
NSMutableString *str = [NSMutableString string]; [str appendString:@"张三"]; Person *per = [[Person alloc]init]; per.name = str; [str appendString:@"与李四"]; NSLog(@"p.name = %@",per.name);
输出:2016-03-21 23:28:01.510 copy[2905:94751] p.name = 张三与李四
因为per.name和str实际上指向同一片内存空间,原因在于,用strong修饰name,只会导致在赋值后赋值对象,str和被赋值对象引用计数+1,并不会产生不可变的副本对象,修改str之后,per.name所指向的内存空间的值发生了改变,因而也会被修改,故而通常我们用copy修饰字符串.
如果不希望per.name被修改,那么在赋值的时候可以这样写:
per.name = str.copy
这样,就不会导致姓名被修改了.