集合对象与非集合对象遵循的规则是一样,不一样的地方在于:
集合对象的深拷贝只是针对集合对象的深拷贝,并不是严格意义上的深拷贝,而是单层深拷贝。
单层深拷贝:对集合对象而言,深拷贝只是将第一层对象也就是该对象进行了深拷贝,而集合对象的元素仍然只是浅拷贝。
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];