先说结论
- 可变对象的copy和mutableCopy都是深拷贝,mutableCopy是单层深拷贝
- 不可变对象的copy是浅拷贝,mutableCopy是深拷贝
- copy出来的是不可变对象,mutableCopy出来的是可变对象
- 如果需要容器类完全深拷贝,容器内元素需要实现NSCopying和NSMutableCopying协议,并且使用带有copyItems的方法
测试
不可变对象
- (void)testInmutable{NSLog(@"================================");NSLog(@" 不可变对象测试");NSLog(@"================================\n");Person *obj = [[Person alloc]init];NSArray *array = [NSArray arrayWithObject:obj];NSMutableArray *mutableArray = [array mutableCopy];NSArray *copyArray = [array copy];NSLog(@"-------------容器类-------------");NSLog(@"array: %p-%@ class:%@",array,array,NSStringFromClass([array class]));NSLog(@"copyArray: %p-%@ class:%@",copyArray,copyArray,NSStringFromClass([copyArray class]));NSLog(@"mutableArray: %p-%@ class:%@\n",mutableArray,mutableArray,NSStringFromClass([mutableArray class]));NSString *str = @"123";NSString *copyStr = [str copy];NSString *mutableStr = [str mutableCopy];NSLog(@"-------------非容器类-------------");NSLog(@"str: %p---%@ class:%@",str,str,NSStringFromClass([str class]));NSLog(@"copyStr: %p---%@ class:%@",copyStr,copyStr,NSStringFromClass([copyStr class]));NSLog(@"mutableStr: %p---%@ class:%@\n",mutableStr,mutableStr,NSStringFromClass([mutableStr class]));}
可变对象
- (void)testMutable{NSLog(@"================================");NSLog(@" 可变对象测试");NSLog(@"================================\n");Person *obj= [[Person alloc]init];obj.mName = @"name";NSMutableArray *array = [NSMutableArray arrayWithObject:obj];NSArray *copyArray = [array copy];NSMutableArray *mutableArray = [array mutableCopy];NSMutableArray *mutableArray1 = [NSMutableArray arrayWithArray:array];NSMutableArray *mutableArray2 = [[NSMutableArray alloc]initWithArray:array copyItems:YES];obj.mName = @"newName";NSLog(@"-------------容器类-------------");NSLog(@"array: %p-%@ class:%@ name:%@",array,array,NSStringFromClass([array class]),((Person *)[array firstObject]).mName);NSLog(@"copyArray: %p-%@ class:%@ name:%@",copyArray,copyArray,NSStringFromClass([copyArray class]),((Person *)[copyArray firstObject]).mName);NSLog(@"mutableArray: %p-%@ class:%@ name:%@",mutableArray,mutableArray,NSStringFromClass([mutableArray class]),((Person *)[mutableArray firstObject]).mName);NSLog(@"mutableArray1: %p-%@ class:%@ name:%@",mutableArray1,mutableArray1,NSStringFromClass([mutableArray1 class]),((Person *)[mutableArray1 firstObject]).mName);NSLog(@"mutableArray2: %p-%@ class:%@ name:%@\n",mutableArray2,mutableArray2,NSStringFromClass([mutableArray2 class]),((Person *)[mutableArray2 firstObject]).mName);NSMutableString *str = [NSMutableString stringWithString:@"123"];NSString *copyStr = [str copy];NSString *mutableStr = [str mutableCopy];NSLog(@"-------------非容器类-------------");NSLog(@"str: %p---%@ class:%@",str,str,NSStringFromClass([str class]));NSLog(@"copyStr: %p---%@ class:%@",copyStr,copyStr,NSStringFromClass([copyStr class]));NSLog(@"mutableStr: %p---%@ class:%@\n",mutableStr,mutableStr,NSStringFromClass([mutableStr class]));}
打印结果
开发时需要注意的
- NSString,NSArray,NSDictionary类型的属性需要用copy修饰
- 因为如果从mutable对象赋值后,copy会深拷贝mutable对象,并且变成不可变类型,这样在mutable对象再有增删操作时不会对copy修饰的属性造成影响,如果是strong修饰的属性就会跟着改变了。但是容器类因为是单层深拷贝,所以如果对元素的某个属性进行修改,copy后的对象也会被修改
