首页 > 代码库 > 深复制与浅复制

深复制与浅复制

  深复制与浅复制 需要遵守NSCopying, NSMutableCopying 2个协议

什么是copyCopy的字面意思是“复制”、“拷贝”,是一个产生副本的过程常见的复制有:文件复制作用:利用一个源文件产生一个副本文件特点:修改源文件的内容,不会影响副本文件修改副本文件的内容,不会影响源文件OC中的copy作用:利用一个源对象产生一个副本对象特点:修改源对象的属性和行为,不会影响副本对象修改副本对象的属性和行为,不会影响源对象

 

如何使用copy功能一个对象可以调用copy或mutableCopy方法来创建一个副本对象copy : 创建的是不可变副本(如NSString、NSArray、NSDictionary)mutableCopy :创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)使用copy功能的前提copy : 需要遵守NSCopying协议,实现copyWithZone:方法@protocol NSCopying- (id)copyWithZone:(NSZone *)zone;@endmutableCopy : 需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法@protocol NSMutableCopying- (id)mutableCopyWithZone:(NSZone *)zone;@end 

 

深复制(深拷贝,内容拷贝,deep copy)源对象和副本对象是不同的两个对象源对象引用计数器不变, 副本对象计数器为1(因为是新产生的)本质是:产生了新的对象浅复制(浅拷贝,指针拷贝,shallow copy)源对象和副本对象是同一个对象源对象(副本对象)引用计数器 + 1, 相当于做一次retain操作本质是:没有产生新的对象

 技术分享

 

实例1 NSString和NSMutableString:

NSString *str1 = @"abc";    NSString *str2 = @"abc";        BOOL isEquals = str1==str2?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSString *str3 = [str1 copy];    isEquals = str3==str2?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSMutableString *str4 = [str1 mutableCopy];    isEquals = str4==str1?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSLog(@"-----------------------");        NSString *str5 = @"abc";    NSMutableString *str6 = [NSMutableString stringWithFormat:@"abc"];    isEquals = str5==str6?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSString *str7 = [str6 copy];    isEquals = str7==str2?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSMutableString *str8 = [str6 mutableCopy];    isEquals = str8==str6?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");

 运行结果:

2015-01-01 14:48:07.742 深复制与浅复制[934:56160] =相同=2015-01-01 14:48:07.743 深复制与浅复制[934:56160] =相同=2015-01-01 14:48:07.743 深复制与浅复制[934:56160] =不相同=2015-01-01 14:48:07.743 深复制与浅复制[934:56160] -----------------------2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=Program ended with exit code: 0

 注意:NSString copy产生的不可变数据对象也是指向原对象,上面str1和str3

实例2 NSArray和NSMutableArray:

 NSArray *array1 = @[@1,@2,@3];    NSArray *array2 = @[@1,@2,@3];        BOOL isEquals = array1 == array2 ? YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSArray *array3 = [array1 copy];    isEquals = array3 == array1 ? YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");    NSMutableArray *array4 = [array1 mutableCopy];    isEquals = array4 == array1 ? YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");//    NSLog(@"%@",array1);//    NSLog(@"%@",array4);    [array4 addObject:@4];//    NSLog(@"%@",array1);    NSLog(@"%@",array4);        NSLog(@"--------------------------");        NSMutableArray *array5 = [NSMutableArray arrayWithObjects:@1,@2,@3, nil];      NSArray *array6 = [array5 copy];    isEquals = array5 == array6 ? YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        NSMutableArray *array8 = [array5 mutableCopy];    isEquals = array5 == array8 ? YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");//    NSLog(@"%@",array8);    [array8 addObject:@4];//    NSLog(@"%@",array5);    NSLog(@"%@",array8);

 运行结果:

2015-01-01 15:00:30.950 深复制与浅复制[980:59234] =不相同=2015-01-01 15:00:30.951 深复制与浅复制[980:59234] =相同=2015-01-01 15:00:30.951 深复制与浅复制[980:59234] =不相同=2015-01-01 15:00:30.952 深复制与浅复制[980:59234] (    1,    2,    3,    4)2015-01-01 15:00:30.952 深复制与浅复制[980:59234] --------------------------2015-01-01 15:00:30.952 深复制与浅复制[980:59234] =不相同=2015-01-01 15:00:30.952 深复制与浅复制[980:59234] =不相同=2015-01-01 15:00:30.952 深复制与浅复制[980:59234] (    1,    2,    3,    4)Program ended with exit code: 0

 注意:NSArray copy产生的不可变数据对象也是指向原对象,上面array1和array3

 

实例4 NSDictionary和NSMutableDictionary 跟上面情况一样:

 

实例5:测试不管产生可变还是不可变对象,数组中存储内容对象都还是指向同一份对象

@interface Person : NSObject //<NSCopying, NSMutableCopying>@property (nonatomic,copy) NSString *name;@property (nonatomic,assign) int age;- (void)eat;- (instancetype)initWithName:(NSString *)name age:(int)age;+ (instancetype)personWithName:(NSString *)name age:(int)age;@end

 

#import "Person.h"@implementation Person- (void)eat{    NSLog(@"%s",__func__);}+ (instancetype)personWithName:(NSString *)name age:(int)age{    return [[self alloc] initWithName:name age:age];}- (instancetype)initWithName:(NSString *)name age:(int)age{    if (self == [super init]) {        self.name = name;        self.age = age;    }    return self;}- (NSString *)description{    return [NSString stringWithFormat:@"name=%@ age=%d",_name,_age];}//- (id)copyWithZone:(NSZone *)zone{//    Person *person = [[Person allocWithZone:zone] init];//    person.name = [self.name copy];//    person.age = self.age;//    return person;//}////- (id)mutableCopyWithZone:(NSZone *)zone{//    Person *person = [[Person allocWithZone:zone] init];//    person.name = [self.name mutableCopy];//    person.age = self.age;//    return person;//}@end

 

Person *p1 = [Person personWithName:@"zhangsan" age:20];    Person *p2 = [Person personWithName:@"lisi" age:21];    Person *p3 = [Person personWithName:@"wangwu" age:22];        NSMutableArray *array1 = [NSMutableArray arrayWithObjects:p1,p2,p3, nil];    NSLog(@"%@",array1);    p1.name = @"zhangsan111";    NSLog(@"%@",array1);        NSArray *array2 = [array1 copy];    NSLog(@"%@",array2);        BOOL isEquals = array1 == array2?YES:NO;    NSLog(@"=%@=",isEquals?@"相同":@"不相同");        isEquals = array1[0] == array2[0];    NSLog(@"=%@=",isEquals?@"相同":@"不相同");

 运行结果:

2015-01-01 15:18:58.814 深复制与浅复制[1100:64607] (    "name=zhangsan age=20",    "name=lisi age=21",    "name=wangwu age=22")2015-01-01 15:18:58.815 深复制与浅复制[1100:64607] (    "name=zhangsan111 age=20",    "name=lisi age=21",    "name=wangwu age=22")2015-01-01 15:18:58.815 深复制与浅复制[1100:64607] (    "name=zhangsan111 age=20",    "name=lisi age=21",    "name=wangwu age=22")2015-01-01 15:18:58.816 深复制与浅复制[1100:64607] =不相同=2015-01-01 15:18:58.816 深复制与浅复制[1100:64607] =相同=

 说明复制后2个数组中存储的内容对象是相同的

 

深复制与浅复制