深拷贝、浅拷贝、mutableCopy、copy

关于深拷贝、浅拷贝的文章有很多,比如深拷贝拷贝的是对象的指针和内存地址的内容;浅拷贝拷贝的是对象的指针,简单来说如下图:

那是不是深拷贝==mutableCopy,浅拷贝==copy呢?

    NSMutableArray *demo1Arr = [NSMutableArray arrayWithObjects:@(1),@(2), nil];
    NSArray *demo2Arr = [demo1Arr copy];
    NSLog(@"demo2Arr:%@",[demo2Arr classForCoder]);
    NSLog(@"demo1Arr地址 = %p,demo2Arr内存地址 = %p\n demo1Arr指针地址 = %x,demo2Arr内存地址 = 
    %x",demo1Arr,demo2Arr,&demo1Arr,&demo2Arr);
    打印日志:
    demo2Arr:NSArray
    demo1Arr内存地址 = 0x600000e681b0,
    demo2Arr内存地址 = 0x60000002df60
    demo1Arr指针地址 = eedf5970,
    demo2Arr内存地址 = eedf5968

我们定义了一个demo1Arr为可变数组,对其进行深拷贝(看打印日志,demo2Arr内存地址和demo1内存地址相同)并赋值给demo2Arr,但是demo2Arr的真实数据类型为不可变数组NSArray

    NSArray *demo1Arr = [NSArray arrayWithObjects:@(1),@(2), nil];
    NSArray *demo2Arr = [demo1Arr copy];
    NSLog(@"demo2Arr:%@",[demo2Arr classForCoder]);
    NSLog(@"demo1Arr地址 = %p,demo2Arr内存地址 = %p\n demo1Arr指针地址 = %x,demo2Arr内存地址 = %x",demo1Arr,demo2Arr,&demo1Arr,&demo2Arr);
    打印日志:
    demo2Arr:NSArray
    demo1Arr内存地址 = 0x6000009759c0,
    demo2Arr内存地址 = 0x6000009759c0
    demo1Arr指针地址 = ec203970,
    demo2Arr内存地址 = ec203968

我们定义了一个demo1Arr为不可变数组,对其进行浅拷贝(看打印日志,demo2Arr内存地址和demo1内存地址相同)并赋值给demo2Arr,则demo2Arr的真实数据类型为不可变数组NSArray

    NSArray *demo1Arr = [NSArray arrayWithObjects:@(1),@(2), nil];
    NSArray *demo2Arr = [demo1Arr mutableCopy];
    NSLog(@"demo2Arr:%@",[demo2Arr classForCoder]);
    NSLog(@"demo1Arr地址 = %p,demo2Arr内存地址 = %p\n demo1Arr指针地址 = %x,demo2Arr内存地址 = %x",demo1Arr,demo2Arr,&demo1Arr,&demo2Arr);
    打印日志:
    demo2Arr:NSMutableArray
    demo1Arr内存地址 = 0x600000d76fe0,
    demo2Arr内存地址 = 0x6000003270f0,
    demo1Arr指针地址 = e78e0970,
    demo2Arr内存地址 = e78e0968

我们定义了一个demo1Arr为不可变数组,对其进行深拷贝(看打印日志,重新创建的数组内存地址和指针地址都是重新创建的)并赋值给demo2Arr,则demo2Arr的真实数据类型为可变数组NSMutableArray

    NSMutableArray *demo1Arr = [NSMutableArray arrayWithObjects:@(1),@(2), nil];
    NSMutableArray *demo2Arr = [demo1Arr mutableCopy];
    NSLog(@"demo2Arr:%@",[demo2Arr classForCoder]);
    NSLog(@"demo1Arr内存地址 = %p,demo2Arr内存地址 = %p\n demo1Arr指针地址 = %x,demo2Arr内存地址 = %x",demo1Arr,demo2Arr,&demo1Arr,&demo2Arr);
    打印日志:
    demo2Arr:NSMutableArray
    demo1Arr内存地址 = 0x600001746f70,
    demo2Arr内存地址 = 0x600001746d90
    demo1Arr指针地址 = e5cad970,
    demo2Arr内存地址 = e5cad968

我们定义了一个demo1Arr为可变数组,对其进行深拷贝(看打印日志,重新创建的数组内存地址和指针地址都是重新创建的)并赋值给demo2Arr,则demo2Arr的真实数据类型为变数组NSMutableArray

    NSMutableArray *demo1Arr = [NSMutableArray arrayWithObjects:@(1),@(2), nil];
    NSMutableArray *demo2Arr = [demo1Arr copy];
    NSLog(@"demo2Arr:%@",[demo2Arr classForCoder]);
    NSLog(@"demo1Arr内存地址 = %p,demo2Arr内存地址 = %p\n demo1Arr指针地址 = %x,demo2Arr内存地址 = %x",demo1Arr,demo2Arr,&demo1Arr,&demo2Arr);
    打印日志:
    demo2Arr:NSArray
    demo1Arr内存地址 = 0x600000290570,
    demo2Arr内存地址 = 0x600000c98040
    demo1Arr指针地址 = e5601970,
    demo2Arr内存地址 = e5601968

我们定义了一个demo1Arr为可变数组,对其进行深拷贝(看打印日志,重新创建的数组内存地址和指针地址都是重新创建的)并赋值给demo2Arr,则demo2Arr的真实数据类型为不变数组NSArray
所以,总结一下:
copy、mutableCopy和浅拷贝、深拷贝并没有什么关系,copy只是拷贝一份不可变对象,是不是深拷贝,取决于它的拷贝源类型,如果拷贝源是不可变对象,这次拷贝为浅拷贝;如果拷贝源为可变对象,则这次拷贝为深拷贝。mutableCopy拷贝一份可变对象,不管拷贝源是何种对象,这次拷贝都是为深拷贝。


2019年3月1日记
在操作NSMutableArray和NSArray的过程中,如果数组的内容是模型数组,即便已经是对NSMutableArray做了深拷贝,那么当你修改数组中的模型属性时,原始数组的模型属性也会相应的被修改,这是因为深拷贝只是对数组指针和内容进行拷贝,也就是说数组的内存地址和内容重复复制了一份。。但是模型的内存地址还是原始数组的内存地址,所以如果操作模型的属性,就会导致原始数组的模型属性的修改,当然处理方法也有,就是给模型类添加协议,并实现两个协议对应的方法,在修改模型属性的时候也进行一次深拷贝

@interface OrderDestiModel : NSObject 

@property (strong,nonatomic)NSString *iID;
@property (strong, nonatomic)NSNumber *multi;
@property (strong, nonatomic)NSString *name;
@property (strong,nonatomic)NSString *en_name;
@property (strong,nonatomic)NSMutableArray *dataArr;
@end
- (nonnull id)copyWithZone:(nullable NSZone *)zone {
    DataModel *model = [[DataModel allocWithZone:zone] init];
    model.dID = self.dID;
    model.isSelect = self.isSelect;
    model.multi = self.multi;
    model.name = self.name;
    model.en_name = self.en_name;
    return model;
}

- (nonnull id)mutableCopyWithZone:(nullable NSZone *)zone {
    DataModel *model = [[DataModel allocWithZone:zone] init];
    model.dID = self.dID;
    model.isSelect = self.isSelect;
    model.multi = self.multi;
    model.name = self.name;
    model.en_name = self.en_name;
    return model;
}

以上为举例说明

你可能感兴趣的:(深拷贝、浅拷贝、mutableCopy、copy)