1.字符串拷贝
copy
浅拷贝,不拷贝对象本身,仅仅是拷贝指向对象的指针。
NSString *str1 = @"qqq";
NSString *str2 = [str1 copy];
NSLog(@"\nstr1 = %@ str1P = %p \n str2 = %@ str2P = %p", str1, str1, str2, str2);
//运行结果
str1 = qqq str1P = 0x101d54100
str2 = qqq str2P = 0x101d54100
str1 = @"sss";
NSLog(@"%@---%@----%p---%p",str1,str2,str1,str2);
//运行结果 sss---qqq----0x1080a4140---0x1080a4100
那为什么NSString *str2 = [str1 copy];
是不同的指针指向同一块内存空间,str1 从新赋值 后两个内存空间就不一样了呢?
因为str2 = str1
的时候,两个字符串都是不可变的,指向的同一块内存空间中的 @"str1"
,是不可能变成@"abcd"
的。所以这个时候,为了优化性能,系统没必要另外提供内存,只生成另外一个指针,指向同一块内存空间就行。
但是当你从新给 str1
或者str2
赋值的时候,因为之前的内容不可变,还有互不影响的原则下,这个时候,系统会从新开辟一块内存空间。
NSMutableString *mstr1 = [[NSMutableString alloc]initWithString:@"123"];
NSMutableString *mstr2 = [mstr1 copy];
NSLog(@"%@---%@--%p---%p",mstr1,mstr2,mstr1,mstr2);
NSMutableString *mstr3 = [mstr1 mutableCopy];
NSLog(@"%@---%p",mstr3,mstr3);
copy 和 mutableCopy 当 immtable 对象调用copy方法 返回的是 immtable对象 immtable 调用 mutablecopy返回 mutable
2.相对数组而言
@property (nonatomic, copy) NSMutableArray *mArr;
NSArray *arr = @[@"123", @"456", @"asd"];
self.mArr = [arr mutableCopy];
NSLog(@"\n arrP = %p \n self.mArrP = %p, self.mArr class = %@", arr, self.mArr, [self.mArr class]);
可以看出内存地址不一样,但是_mArr
是不可变的数组。
因为 _mArr
声明的时候是用 copy
修饰,那么就限制了他为不可变的数组。 赋值的时候是用mutableCopy
,可变数组的复制方法,所以会从新分配内存。
//运行结果
arrP = 0x600003a6ebb0
self.mArrP = 0x600003a6eb20, self.mArr class = __NSArrayI
- 用copy修饰的 或者赋值的 变量肯定是不可变的。
- 用copy赋值,要看源对象是否是可变的,来决定只拷贝指针,还是也拷贝对象到另一块内存空间
- 对象之间mutableCopy赋值,肯定会拷贝整个对象内存到另一块内存中
- 对象之间赋值之后,再改变,遵循互不影响的原则