copy
一个对象要能够copy,就得遵守NSCopying协议,并实现copyWithZone协议方法。
测试直接赋值地址:
NSString *str1 = @"小花";
NSString *str2 = [str1 copy];
NSLog(@"str1 %@ %p",str1,str1);
NSLog(@"str2 %@ %p",str2,str2);
str1 = @"花菜";
NSLog(@"str1 %@ %p",str1,str1);
NSLog(@"str2 %@ %p",str2,str2);
打印:
[10830:577327] str1 小花 0x10baf43c0
[10830:577327] str2 小花 0x10baf43c0
[10830:577327] str1 花菜 0x10baf4420
[10830:577327] str2 小花 0x10baf43c0
当用copy拷贝不可变字符串时,拷贝了一个指针,所指向的地址和值都一样。其指向被拷贝对象当前的值。
测试NSString间接赋值地址:
NSString *str = @"小花";
NSLog(@"str %@ %p",str,str);
NSString *str1 = str;
NSString *str2 = [str1 copy];
NSLog(@"str1 %@ %p",str1,str1);
NSLog(@"str2 %@ %p",str2,str2);
str = @"花菜";
NSLog(@"str %@ %p",str,str);
NSLog(@"str1 %@ %p",str1,str1);
NSLog(@"str2 %@ %p",str2,str2);
打印:
[11322:610374] str 小花 0x10cd6e3c0
[11322:610374] str1 小花 0x10cd6e3c0
[11322:610374] str2 小花 0x10cd6e3c0
[11322:610374] str 花菜 0x10cd6e440
[11322:610374] str1 小花 0x10cd6e3c0
[11322:610374] str2 小花 0x10cd6e3c0
从str间接赋值,改变str字符串的值后也并不影响其它字符串的值。
测试copy和strong修饰的字符串地址:
#import
@interface Person : NSObject
@property (nonatomic, copy) NSString *strCopy;
@property (nonatomic, strong) NSString *strStrong;
@end
1.测试直接赋值:
Person *p1 = [[Person alloc] init];
p1.strCopy = @"小明";
p1.strStrong = @"王小明";
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
//修改
p1.strCopy = @"小明明";
p1.strStrong = @"王大明";
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
打印:
[11472:620824] strCopy 小明 0x10eb9a460
[11472:620824] strStrong 王小明 0x10eb9a480
[11472:620824] strCopy 小明明 0x10eb9a4e0
[11472:620824] strStrong 王大明 0x10eb9a500
修改值后地址都会改变,相当于一级指针指向新值。
2.测试NSString间接赋值:
NSString *string = @"明明";
NSLog(@"string %@ %p",string,string);
Person *p1 = [[Person alloc] init];
p1.strCopy = string;
p1.strStrong = string;
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
//修改
string = @"很爱你";
NSLog(@"string %@ %p",string,string);
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
打印:
[11807:640600] string 明明 0x10afbd3c0
[11807:640600] strCopy 明明 0x10afbd3c0
[11807:640600] strStrong 明明 0x10afbd3c0
[11807:640600] string 很爱你 0x102862440
[11807:640600] strCopy 明明 0x10afbd3c0
[11807:640600] strStrong 明明 0x10afbd3c0
修改string后对strCopy 和strStrong都没有影响。
3.测试NSMutableString间接赋值:
NSMutableString *string = [NSMutableString stringWithFormat:@"明明"];
NSLog(@"string %@ %p",string,string);
Person *p1 = [[Person alloc] init];
p1.strCopy = string;
p1.strStrong = string;
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
//修改
[string appendFormat:@"很爱你"];
NSLog(@"string %@ %p",string,string);
NSLog(@"strCopy %@ %p",p1.strCopy,p1.strCopy);
NSLog(@"strStrong %@ %p",p1.strStrong,p1.strStrong);
打印:
[11707:634460] string 明明 0x604000446090
[11707:634460] strCopy 明明 0x604000025880
[11707:634460] strStrong 明明 0x604000446090
[11707:634460] string 明明很爱你 0x604000446090
[11707:634460] strCopy 明明 0x604000025880
[11707:634460] strStrong 明明很爱你 0x604000446090
这儿发现用copy修饰的字符串的地址变了,NSMutableString字符串对象的地址没有变,因而strong修饰的字符串直接指向原地址。
总结:
- NSString的字符串的对象的值改变时,会开辟一块新的内存,NSMutableString的字符串的对象的值改变时,依旧是原地址。
- copy拷贝NSSting字符串时,拷贝指针,既浅拷贝;copy拷贝NSMutableString字符串时是重新生成一个新对象,即深拷贝。copy修饰的可变字符串属性类型始终是NSString,而不是NSMutableString,如果想让拷贝过来的对象是可变的,就要使用mutableCopy。(所有copy修饰的NSSting字符串不会被外界影响)
- strong表示强指向,对可变和不可变字符串都只有浅拷贝。对NSMutableString不存在深拷贝。
参考:
https://wenku.baidu.com/view/fe3752e32af90242a995e50d.html
http://www.cocoachina.com/ios/20150512/11805.html