美文网首页iOS开发攻城狮的集散地
记: NSString是用copy 还是 strong ?

记: NSString是用copy 还是 strong ?

作者: overla5 | 来源:发表于2018-09-05 17:27 被阅读27次

 

1.当源字符串是不可变的时候

对源头是NSString的字符串,无论是strong声明的变量还是copy声明的变量,当第二次源头的字符串重新指向其它的地方的时候,它还是指向原来的最初的那个位置
二者都是指针引用,也就是浅拷贝
浅拷贝 / 指针拷贝: 增加一个指针, 并且申请一个新的内存, 使新指针指向新内存

// 创建2种str
@property (nonatomic, strong) NSString *strongStr; 
@property (nonatomic,   copy) NSString *copyedStr;

// 初始化一个不可变str,赋值为abcd

NSString * tempStr = @"abcd";
self.strongStr = tempStr;
self.copyedStr = tempStr;

// 1、前者是字符串 “xxxx” 内存首地址
// 2、后者是指针str 内存首地址
NSLog(@"Str ----- %@  %p  %p",Str,Str,&Str);
// 打印地址
tempStr   ----- abcd  0x1024031b8  0x7ffeed7fcb08
strongStr ----- abcd  0x1024031b8  0x7ff288c05540
copyedStr ----- abcd  0x1024031b8  0x7ff288c05548
// 重新赋值为efg
tempStr = @"efg";

tempStr   ----- efg   0x102403238  0x7ffeed7fcb08
strongStr ----- abcd  0x1024031b8  0x7ff288c05540
copyedStr ----- abcd  0x1024031b8  0x7ff288c05548

# strongStr 和  copyedStr 内容都还是abcd
# 无论是copy还是strong,都依然指向原来的地址,即为源字符串abcd指向的地址
# tempStr 改变不影响其他2个值的变化

 

2.当源字符串是可变的时候

对源头是NSMutableString的字符串,strong仅仅是指针引用,增加了引用计数器,这样源头改变的时候,用这种strong方式声明的变量(无论被赋值的变量是可变的还是不可变的 ,它也会跟着改变;而copy声明的变量,它不会跟着源头改变,是深拷贝
深拷贝 / 对象拷贝: 在有指针的情况下, 增加一个指针指向已经存在的内存 (OC中引用计数会+1)

 NSMutableString * tempStr = [NSMutableString stringWithFormat:@"abcd"];
 self.strongStr = tempStr;
 self.copyedStr = tempStr;
   
 // 打印地址
tempStr   ----- abcd  0x60000024f570  0x7ffee9ecbb08
strongStr ----- abcd  0x60000024f570  0x7feced6069b0
copyedStr ----- abcd  0xa000000646362614  0x7feced6069b8
 // 源字符串进行拼接
[tempStr appendString:@"efg"]; 

tempStr   ----- abcdefg  0x60000024f570  0x7ffee9ecbb08
strongStr ----- abcdefg  0x60000024f570  0x7feced6069b0
copyedStr ----- abcd  0xa000000646362614  0x7feced6069b8
 
# strongStr  内容是abcdefg,copyedStr 内容还是abcd
# strongStr的类型实际上是NSMutableString,而不是NSString
# copy 对 源字符串进行了深拷贝,指向了新的地址,所以没有随之改变

 

结论:
我们声明NSString的时候最好使用copy,既然NSString是不可变的含义,我们就确保它不会发生改变

 
tips:即使copy修饰的属性是一个可变对象,发生了内存拷贝,但是其实拷贝出来的对象依然是不可变的

@property (nonatomic,   copy) NSMutableString *copyedStr;
   
NSMutableString *tempName = [NSMutableString stringWithString:@"hello"];
self.copyedStr = tempName;
[self.copyedStr appendString:@" world"];

# 会崩溃,copyedStr 本质是不可变的

相关文章

网友评论

    本文标题:记: NSString是用copy 还是 strong ?

    本文链接:https://www.haomeiwen.com/subject/xgmawftx.html