关于深拷贝浅拷贝

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方法,都是浅拷贝!!!

浅拷贝复制容器,深拷贝复制容器及其内部元素

posted @ 2017-09-13 17:20  Mr.pengge  阅读(266)  评论(0编辑  收藏  举报