浅复制只复制对象本身,对象里的属性、包含的对象不做复制 深复制复制全部,包括对象的属性和其他对象Foundation框架支持复制的类,默认是浅复制
NSMutableArray *array=[[NSMutableArray alloc] init]; NSLog(@"数组的地址为 %p",array); for(int i=0;i<3;i++) { NSObject *obj=[[NSObject alloc] init]; [array addObject:obj]; } for(NSObject *obj1 in array) { NSLog(@"地址为 %p",obj1); } NSMutableArray *array2=[array copy]; for(NSObject *obj2 in array2) { NSLog(@"地址为 %p",obj2); } NSLog(@"数组的地址为 %p",array2); NSString * str1 = [[NSMutableString alloc]init]; NSLog(@"字符串的地址是 %p",str1); NSString * str2 = [str1 copy]; NSLog(@"字符串深复制的地址是 %p",str2); NSString * str3 = str1; NSLog(@"字符串浅复制的地址是 %p",str3)
从打印结果可以看出
a、对于数组,浅复制的话只复制了数组的地址,而数组里面的元素仍未复制,如果想要复制里面的元素,则需要实现深复制;
b、对于字符串,浅复制的话只是增加了对字符串地址的引用,计数器+1,深复制对字符串进行了重新开辟了空间,地址变化
NSArray *array=[NSArray arrayWithObjects:@"one",@"two", nil]; NSMutableArray *array1=[array copy]; //array1的地址跟array地址一样,相当于浅复制 [array1 addObject:@"three"]; //这里执行错误 NSMutableArray *array2=[array mutableCopy]; // array2的地址跟array地址不一样 [array2 addObject:@"three"]; //执行正确 NSMutableArray * array3 =[[NSMutableArray alloc] init]; NSLog(@"地址为 %p",array3); NSMutableArray * array4 = [array3 copy]; NSLog(@"地址为 %p",array4);
a、copy返回一个不可变对象的副本,MutalbeCopy返回一个可变对象的副本
b、array1地址与array地址一样,是因为Foundation对于copy不可变(NSArray,NSString之类)对象而言,默认都是浅拷贝,相当于retain,当然此时用mutableCopy相当于copy功能
同样,对于可变对象进行copy操作时,相当于copy而非retain,此时copy的对象不可变,如果需要可变则mutableCopy
c、array2地址与array地址不一样,相当于实现了数组的复制功能,当然如果需要对里面的元素进行复制,需要实现深度复制
2.深复制
对象拥有深复制特性,必须实现NSCopying,NSMutableCopying协议,实现该协议的copyWithZone方法和mutableCopyWithZone方法深拷贝和浅拷贝的区别就在于copyWithZone方法的实现
@interface Person : NSObject<NSMutableCopying> @property(nonatomic,copy)NSString *name; @property(nonatomic,copy)NSString *age; @end @implementation Person - (id)mutableCopyWithZone:(NSZone *)zone { Person *person=[[self class] allocWithZone:zone]; person.age=[_age mutableCopy]; person.name=[_age mutableCopy]; return person; } @end Person *person=[[Person alloc] init]; person.name=@"andy"; person.age=@"20"; Person *person2=[person copy]; NSLog(@"地址为 %p",person); NSLog(@"地址为 %p",person2); NSLog(@"地址为 %p",person.name); NSLog(@"地址为 %p",person2.name);
NSMutableArray * array2 = [[NSMutableArray alloc] initWithArray:array1 copyItems:YES];
打印出来结果是不仅仅复制了person地址,person中的对象地址也进行了复制
实现数组的深度复制,复制的不仅仅是数组本身,数组中的元素也被复制