在讲述之前,首先要明确一个问题:
用copy就是为了解决->当把一个可变字符串赋值给一个属性(name)时,修改了可变字符串的值,从而导致此name属性的值也随之发生改变的问题
在此之前,先了解一下深拷贝和浅拷贝
- 浅拷贝:只是拷贝了指针
- 深拷贝:直接拷贝了对象
- NSString的copy操作是浅拷贝
- NSString的mutableCopy,NSMutableString的copy, NSMutableString的mutableCopy都是深拷贝
先上一段代码
@property (nonatomic, strong)NSString * name;
NSMutableString * strM = [[NSMutableString alloc]initWithString:@"hehe"];
NSLog(@"strM = %@",strM);
self.name = strM;
[strM appendString:@"heng"];
NSLog(@"strM = %@, self.name = %@",strM,self.name);
//输出结果:strM = heheheng, self.name = heheheng
然后我们来分析,
1.指针strM指向了内存中的“hehe”
2.将strM这个指针复制给了self.name这个指针
3.所以这两个指针指向同一块内存,也就是“hehe”
4.那么修改了strM指针对应内存中的值,self.name也同步被修改
这个很容易理解,也就是浅拷贝
接下来我们来看另一段代码
//只把strong修饰符改成了copy
@property (nonatomic, copy)NSString * name;
NSMutableString * strM = [[NSMutableString alloc]initWithString:@"hehe"];
NSLog(@"strM = %@",strM);
self.name = strM;
[strM appendString:@"heng"];
NSLog(@"strM = %@, self.name = %@",strM,self.name);
//输出结果:strM = heheheng, self.name = hehe
然后我们来分析,
1.指针strM指向了内存中的“hehe”
2.将strM这个指针复制给了self.name这个指针
3.self.name这个指针触发copy操作,重新在内存copy了一份“hehe”,并指向了重新copy的这份内存“hehe”
3.所以这两个指针指向的并不少同一块内存,指向的是新copy出来的“hehe”
4.那么修改了strM指针指向的内存中旧的“hehe”的值,self.name也就当然不会被同步修改
这个也就是深拷贝
这还没有结束,肯定有人会提出,那原字符串是不可变字符串呢?
一句话说明
如果是不可变字符串,没有append操作
执行strM = @“heng”这样的操作,只是将strM这个指针重新指向了内存中的“heng”这个对象
所以并不会影响到self.name(不管self.name是用strong还是copy修饰的)
有兴趣的自己敲代码试试就好,欢迎大佬指正