iOS的浅拷贝与深拷贝

先上结论:

  1. 对于不可变对象而言(NSString, NSArray, NSDictionary),copy操作是浅拷贝,mutableCopy操作是深拷贝。copy操作,包括[str copy] 和 @proprety(copy),因为@proprety(copy)在setter方法内部,也有[str copy]操作,下同
  2. 对于可变对象而言(NSMutableString, NSMutableArray, NSMutableDictionary),copy操作和mutableCopy操作都是深拷贝,但是copy出来的对象是不可变的,而mutableCopy出来的对象是可变的
  3. 对于容器类型来说(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]);
}

你可能感兴趣的:(iOS的浅拷贝与深拷贝)