集合对象与非集合对象的拷贝

182 阅读2分钟

集合对象与非集合对象遵循的规则是一样,不一样的地方在于:

集合对象的深拷贝只是针对集合对象的深拷贝,并不是严格意义上的深拷贝,而是单层深拷贝。
单层深拷贝:对集合对象而言,深拷贝只是将第一层对象也就是该对象进行了深拷贝,而集合对象的元素仍然只是浅拷贝。

1、非集合对象的拷贝

该Person类已经实现了NSCopy协议,非集合对象只要实现了NSCopy协议,不管是copy还是mutableCopy都会对该对象进行深拷贝

Person *person = [Person new];    
person.name = @"李四";
person.age = 18;

Person *person2 = [person copy];
Person *perspn3 = [person mutableCopy];

NSLog(@"\nperson:%@\nperson2:%@\nperson3:%@\n",person,person2,perspn3);


2、集合对象的拷贝

这里的集合对象我们已数组为例。

(1)、NSArray的拷贝

NSArray的copy仍然是浅拷贝。

Person *person = [Person new];
person.name = @"李四";
person.age = 18;

NSArray *array = @[person];
NSArray *array2 = [array copy];
NSLog(@"\narray:%p\narray2:%p\n",array,array2);


NSArray的mutableCopy是深拷贝。

NSMutableArray *muArray = [array mutableCopy];
NSLog(@"\nmuArray:%p",muArray);


(2)、NSMutableArray的拷贝

NSMutableArray的copy和mutableCopy都是深拷贝。

Person *person = [Person new];
person.name = @"李四";
person.age = 18;

NSMutableArray *muArray = [NSMutableArray arrayWithArray:@[person]];
NSArray *array = [muArray copy];
NSMutableArray *muArray2 = [muArray mutableCopy];
NSLog(@"\nmuArray:%p\narray:%p\nmuArray2:%p",muArray,array,muArray2);


但是以上所说的关于NSArray、NSMutableArray的深浅拷贝都是只针对NSArray、NSMutableArray,里面的元素也就是person对象,其实还只是浅拷贝,也就是单层深拷贝,要想达到真正意义上的深拷贝还需要对person对象进行深拷贝。

3、对集合对象和集合对象元素进行深拷贝

NSMutableArray *muArray = [NSMutableArray arrayWithArray:@[person]];
NSArray *array2 = [[NSArray alloc] initWithArray:muArray copyItems:YES];
NSLog(@"\nmuArray:%p\nmuArray person:%@\narray2:%p\narray2 person:%@",muArray,muArray.firstObject,array2,array2.firstObject);


或者通过直接对元素进行深拷贝

NSMutableArray *muArray = [NSMutableArray arrayWithArray:@[person]];
NSMutableArray *muArray3 = [NSMutableArray array];
for (Person *person in muArray) {
    [muArray3 addObject:[person copy]];
}
NSLog(@"\nmuArray:%p\nmuArray person:%@\nmuArray3:%p\nmuArray3 person:%@\n",muArray,muArray.firstObject,muArray3,muArray3.firstObject);


4、常见错误

@property (nonatomic, copy) NSMutableArray *arr;

- (void)arrMCopyTest {

    NSMutableArray *arrM = [NSMutableArray arrayWithObjects:@"123",@"456", nil];

    self.arr = arrM;

    // 下面代码崩溃

    [self.arr addObject:@"789"];
}

因为self.arr为copy修饰,那么self.arr = arrM就相当于_arr = [arrM copy];