copy和mutableCopy实践

首先说下两个基本定义:
浅复制:只copy指针而不是copy实际的资源,两个实例指向内存中统一资源。
深复制:不仅复制指针还复制指针,还复制指针所指向的资源,副本对象的指针指向内存中不同位置的同一资源的副本。

不可变对象的copy和mutableCopy操作:

不可变数组
NSArray *arr = [NSArray array];
NSMutableArray  *arr1 = arr.copy;
NSMutableArray *arr2 = arr.mutableCopy;
NSLog(@"%p--%p--%p",arr,arr1,arr2);//0x60800001a1b0--0x60800001a1b0--0x608000047290 
[arr2 insertObject:@"1" atIndex:0];//插入元素成功
[arr1 insertObject:@"1" atIndex:0];//'-[__NSArray0 insertObject:atIndex:]: unrecognized selector sent to instance

 不可变字典
 NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
 NSMutableDictionary *dicM = dict1.copy;
 NSMutableDictionary *dicM1 = dict1.mutableCopy;
 NSLog(@"%p--%p--%p",dict1,dicM,dicM1);//0x6000002641c0--0x6000002641c0--0x600000045280
 [dicM1 removeObjectForKey:@"key1"];
    Printing description of dicM1:
   {
      key2 = value2;
   }

 [dicM removeObjectForKey:@"key1"];//-[__NSDictionaryI removeObjectForKey:]: unrecognized selector sent to instance

 不可变字符串
 NSString *str = @"123";
 NSMutableString *strM1 = str.copy;
 NSMutableString *strM2 = str.mutableCopy;
 NSLog(@"%p--%p--%p",str,strM1,strM2);// 0x1047ee068--0x1047ee068--0x608000079800
 [strM2 appendString:@"4"];//Printing description of strM2:
1234
 [strM1 appendString:@"5"]; //Attempt to mutate immutable object with appendString:   

结论:对不可变对象进行copy操作,不会开辟新的内存,copy的只是内存地址;对不可变对象进行mutableCopy操作,会开辟新的内存,拷贝出的对象是可变的;

可变对象的copy和mutableCopy操作:

可变数组
NSMutableArray *arrM = [NSMutableArray arrayWithCapacity:0];
NSMutableArray *arrM1 = arrM.copy;
NSMutableArray *arrM2 = arrM.mutableCopy;
NSLog(@"%p--%p--%p",arrM,arrM1,arrM2);//arrM:0x608000047e60--arrM1:0x60800000f160--arrM2:0x608000047ce0
[arrM insertObject:@"2" atIndex:0];
[arrM2 insertObject:@"3" atIndex:0];
[arrM1 addObject:@"1"];//-[__NSArray0 addObject:]: unrecognized selector sent to instance


可变字典
NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1",@"key1",@"value2",@"key2", nil];
NSMutableDictionary *dicM = dict1.copy;
NSMutableDictionary *dicM1 = dict1.mutableCopy;
NSLog(@"%p--%p--%p",dict1,dicM,dicM1);//0x60000005d7f0--0x600000074780--0x60000005b810
[dicM1 removeObjectForKey:@"key1"];
 Printing description of dicM1:
   {
      key2 = value2;
   }

[dicM removeObjectForKey:@"key1"];//-[__NSDictionaryI removeObjectForKey:]: unrecognized selector sent to instance

可变字符串
NSMutableString *str = [NSMutableString stringWithCapacity:0]; 
NSMutableString *strM1 = str.copy;
NSMutableString *strM2 = str.mutableCopy;
NSLog(@"%p--%p--%p",str,strM1,strM2);//0x6080000716c0--0x103d94570--0x608000071680
[strM2 appendString:@"4"];//Printing description of strM2:
4
[strM1 appendString:@"5"];//Attempt to mutate immutable object with appendString:

结论:对可变对象进行copy操作,会开辟新的内存,拷贝出的对象是不可变的;对可变对象进行mutableCopy操作,会开辟新的内存,拷贝出的对象是可变的;

关于有可变类型的不可变类(如NSDictionary,NSArray,NSString),声明属性时内存管理关键字为什么要用copy?

用strong声明结果如下:

copy和mutableCopy实践_第1张图片
strong.png
copy和mutableCopy实践_第2张图片
arrStrong.png
copy和mutableCopy实践_第3张图片
strStrong.png

用copy声明结果如下:

copy和mutableCopy实践_第4张图片
copy.png
copy和mutableCopy实践_第5张图片
arrCopy.png
copy和mutableCopy实践_第6张图片
strCopy.png

属性为可变类型,用strong定义,当属性赋值时接收的对象为可变对象,而该可变对象的值改变时,属性的值也跟着改变了。而用copy修饰,赋值时会拷贝出一个新的不可变对象,不受该可变对象影响;

从上面的结果能看出copy不等于浅复制,而mutableCopy一定是深复制。这是因为拷贝后只要副本和原对象之间相互不影响即可,对于OC中这些不可变的对象,因为他们的值是不能修改的,所以副本和原对象之间满足相互不影响,没必要新开辟内存空间拷贝一份资源。

你可能感兴趣的:(copy和mutableCopy实践)