关于深拷贝浅拷贝
There are two kinds of object copying: shallow copies and deep copies. The normal copy is a shallow copy that produces a new collection that shares ownership of the objects with the original. Deep copies create new objects from the originals and add those to the new collection.
以上三句出自于苹果官方文档 Collections.pdf。
意思大致如下:
有两种类型的对象拷贝,浅拷贝和深拷贝。正常的拷贝,生成一个新的容器,但却是和原来的容器共用内部的元素,这叫做浅拷贝。深拷贝不仅生成新的容器,还生成了新的内部元素。
In
the case of these objects, a shallow copy means that a new collection object is created,
but the contents of the original collection are not duplicated—only the object references are copied to the new container.
A deep copy duplicates the compound object as well as the contents of all of its contained objects.
以上两句出自于苹果官方文档 CFMemoryMgmt.pdf。
OK,有官方文档为证。浅拷贝复制容器,深拷贝复制容器及其内部元素。
浅copy示例:
NSMutableArray *newArray = [self.dataArr mutableCopy]; WeekModel *model = [newArray objectAtIndex:indexPath.row]; if ([model.isCheck isEqualToString:@"1"]) { model.isCheck = @"0"; } else { model.isCheck = @"1"; } ChooseCell *cell = [tableView cellForRowAtIndexPath:indexPath]; [cell setCheckd:[self.dataArr objectAtIndex:indexPath.row]]; //如上代码虽然使用的是mutableCopy,但依旧是浅copy,与使用copy意义是一样的其实;因此仅仅是copy的数组容器,并没有开辟新空间容纳数组内的数据,因此newArray中数据更改时,对应的self.dataArr的数据也是在更改;
深copy示例:
//深copy
NSMutableArray *newArray = [[NSMutableArray alloc] initWithArray:self.dataArr copyItems:YES]; WeekModel *model = [newArray objectAtIndex:indexPath.row]; if ([model.isCheck isEqualToString:@"1"]) { model.isCheck = @"0"; } else { model.isCheck = @"1"; } // 该代码就是self.dataArr替换更改过的model [self.dataArr replaceObjectAtIndex:indexPath.row withObject:model]; ChooseCell *cell = [tableView cellForRowAtIndexPath:indexPath]; [cell setCheckd:[self.dataArr objectAtIndex:indexPath.row]];
如上就是深copy的实现方式,因此重新开辟新空间以供数组元素存储,因此newArray中model发生改变时,并不会影响self.dataArr的数据。
不过使用深copy时需要注意一点:需要对自定义的model重写copyWithZone:方法
//.h文件
@interface WeekModel : NSObject @property (strong, nonatomic) NSString *weekId; @property (strong, nonatomic) NSString *weekName; @property (assign, nonatomic) NSString *isCheck; - (instancetype)initWithId:(NSString *)weekId weekName:(NSString *)weekName isCheck:(NSString *)isCheck; - (id)copyWithZone:(NSZone *)zone;
//.m文件
- (instancetype)initWithId:(NSString *)weekId weekName:(NSString *)weekName isCheck:(NSString *)isCheck { self = [super init]; if (self) { self.weekId = weekId; self.weekName = weekName; self.isCheck = isCheck; } return self; } - (id)copyWithZone:(NSZone *)zone { WeekModel *model = [[WeekModel allocWithZone:zone] init]; model.weekId = self.weekId; model.weekName = self.weekName; model.isCheck = self.isCheck; return model; }
最后来总结一下:
所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!!
浅拷贝复制容器,深拷贝复制容器及其内部元素