先上结论:
- 对于不可变对象而言(NSString, NSArray, NSDictionary),copy操作是浅拷贝,mutableCopy操作是深拷贝。copy操作,包括[str copy] 和 @proprety(copy),因为@proprety(copy)在setter方法内部,也有[str copy]操作,下同
- 对于可变对象而言(NSMutableString, NSMutableArray, NSMutableDictionary),copy操作和mutableCopy操作都是深拷贝,但是copy出来的对象是不可变的,而mutableCopy出来的对象是可变的
- 对于容器类型来说(NSMutableArray, NSMutableDictionary),mutableCopy 仅仅拷贝了第一层,所以是不完全深拷贝
直接上验证代码:
NSString
- (void)stringCopy {
// str copy 是浅拷贝,mutableCopy是深拷贝
NSString *str = @"testStr";
NSString *str1 = [str copy];
NSMutableString *str2 = [str mutableCopy];
NSLog(@"str:%@,%p", str, str); // str:testStr,0x10ac23020
NSLog(@"str1:%@,%p", str1, str1); // str1:testStr,0x10ac23020
NSLog(@"str2:%@,%p", str2, str2); // str2:testStr,0x60000112b720
str1 = @"abc"; // str1重新赋值 // 重新赋值,不影响前面指针指向
[str2 appendString:@" mutStrAppend"]; // str2 appendString
NSLog(@"str:%@,%p", str, str); // str:testStr,0x10ac23020
NSLog(@"str1:%@,%p", str1, str1); // str1:abc,0x1090fe0a0
NSLog(@"str2:%@,%p", str2, str2); // str2:testStr mutStrAppend,0x6000009e39f0
// mutableString copy 和 mutableCopy 都是深拷贝
NSMutableString *mutStr = [[NSMutableString alloc] initWithString:@"123"];
NSString *mutStrCopy = [mutStr copy];
NSMutableString *mutStrMutCopy = [mutStr mutableCopy];
NSLog(@"mutStr:%@,%p", mutStr, mutStr); // mutStr:123,0x6000039cf6c0
NSLog(@"mutStrCopy:%@,%p", mutStrCopy, mutStrCopy); // mutStrCopy:123,0x984f4eaff626b56e
NSLog(@"mutStrMutCopy:%@,%p", mutStrMutCopy, mutStrMutCopy); // mutStrMutCopy:123,0x6000039ce850
}
NSArray
- (void)arrayCopy {
// array
// 对array copy 浅拷贝,mutableCopy 深拷贝 ,但是,mutableCopy后,arrMutablecopy里面的元素 与 原arr里面的元素地址相同,所以array的mutableCopy是不完全深拷贝,只深拷贝了第一层,没有深拷贝内层
NSMutableString *testStr = [@"123" mutableCopy];
NSArray *arr = @[@"1", @"2", testStr];
NSArray *arrCopy = [arr copy];
NSMutableArray *arrMutablecopy = [arr mutableCopy];
NSLog(@"arr:%@,%p \nobjectP:%p", arr, arr, arr[0]); // arr:(1, 2),0x600002979e60 , objectP:0x10623c168
NSLog(@"arrCopy:%@,%p \nobjectP:%p", arrCopy, arrCopy, arrCopy[0]); // arr:(1, 2),0x600002979e60 , objectP:0x10623c168
NSLog(@"arrMutablecopy:%@,%p \nobjectP:%p", arrMutablecopy, arrMutablecopy, arrMutablecopy[0]); // arrMutablecopy:(1,2),0x60000270a430 ,objectP:0x10623c168
[testStr appendString:@"45"];
NSLog(@"arr:%@,%p \nobjectP:%p", arr, arr, arr[0]); // arr:(1, 2, 12345),0x600002979e60 , objectP:0x10623c168
NSLog(@"arrCopy:%@,%p \nobjectP:%p", arrCopy, arrCopy, arrCopy[0]); // arr:(1, 2, 12345),0x600002979e60 , objectP:0x10623c168
NSLog(@"arrMutablecopy:%@,%p \nobjectP:%p", arrMutablecopy, arrMutablecopy, arrMutablecopy[0]); // arrMutablecopy:(1,2,12345),0x60000270a430 ,objectP:0x10623c168
// mutableArray
NSMutableString *mutarrTestStr = [@"abc" mutableCopy];
NSMutableArray *mutarr = [NSMutableArray arrayWithObjects:@"123", mutarrTestStr, nil];
NSArray *mutarrCopy = [mutarr copy];
NSMutableArray *mutarrMutablecopy = [mutarr mutableCopy];
NSLog(@"mutarr:%@,%p \nobjectP:%p", mutarr, mutarr, mutarr[0]); // arr:(123, abc),0x600001396460 , objectP:0x1015bc0e8
NSLog(@"mutarrCopy:%@,%p \nobjectP:%p", mutarrCopy, mutarrCopy, mutarrCopy[0]); // arr:(123, abc),0x600001396460 , objectP:0x1015bc0e8
NSLog(@"mutarrMutablecopy:%@,%p \nobjectP:%p", mutarrMutablecopy, mutarrMutablecopy, mutarrMutablecopy[0]); // arrMutablecopy:(123,abc),0x60000270a430 , objectP:0x1015bc0e8
[mutarrTestStr appendString:@"456"];
NSLog(@"mutarr:%@,%p \nobjectP:%p", mutarr, mutarr, mutarr[0]); // arr:(123, abc456),0x600001396460 , objectP:0x1015bc0e8
NSLog(@"mutarrCopy:%@,%p \nobjectP:%p", mutarrCopy, mutarrCopy, mutarrCopy[0]); // arr:(123, abc456),0x600001396460 , objectP:0x1015bc0e8
NSLog(@"mutarrMutablecopy:%@,%p \nobjectP:%p", mutarrMutablecopy, mutarrMutablecopy, mutarrMutablecopy[0]); // arrMutablecopy:(123,abc456),0x60000270a430 , objectP:0x1015bc0e8
// 1.对于不可变对象而言,copy便是浅拷贝,mutableCopy是深拷贝
// 2.对于可变对象而言,copy和mutableCopy都是深拷贝,但是copy出来的对象是不可变的,而mutableCopy出来的对象是可变的
// 3. 对于容器类型来说,mutableCopy 仅仅拷贝了第一层,所以是不完全深拷贝
}
完全深拷贝示例
// 完全深拷贝实现
- (void)totalMutcopy {
NSMutableArray *marry1 = [[NSMutableArray alloc] init];
NSMutableString *mstr1 = [[NSMutableString alloc]initWithString:@"Cooci"];
NSMutableString *mstr2 = [[NSMutableString alloc]initWithString:@"Gavin"];
[marry1 addObject:mstr1];
[marry1 addObject:mstr2];
NSLog(@"marry1:%p - %@ \r\n",marry1,marry1);
NSLog(@"marry1数组元素地址:value1:%p - value2:%p \r\n",marry1[0],marry1[1]);
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:marry1];
NSArray *marray2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];
[mstr1 appendString:@"123"];
NSLog(@"marry1:%p - %@ \r\n",marry1,marry1);
NSLog(@"marry1数组元素地址:value1:%p - value2:%p \r\n",marry1[0],marry1[1]);
NSLog(@"marry2:%p - %@ \r\n",marray2,marray2);
NSLog(@"marry2数组元素地址:value1:%p - value2:%p \r\n",marray2[0],marray2[1]);
}