深copy和浅copy

在iOS中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying 协议的类可以发送copy消息,遵守NSMutableCopying 协议的类才可以发送mutableCopy消息。

所谓浅拷贝,即单纯的地址拷贝,并不产生新的对象,而是对原对象的引用计数值加1;而深拷贝,即是对象拷贝,产生新的对象副本,拥有独立的内存空间,引用计数器为1。

系统类对象copy/mutablecopy

我们常用的有NSString/NSMutableString、NSArray/NSMutableArray、NSDictionary/NSMutableDictionary、NSSet、NSMutableSet等系统类对象,下面我们来验证什么情况下是深拷贝,什么情况下是浅拷贝。

先看代码:

NSString和NSMutableString
//    1.NSString NSMutableString -> COPY
    NSString *str = @"abc";
    NSString *str1 = [str copy];
    NSLog(@"%p %p",str,str1);
    
    NSMutableString *mStr = [[NSMutableString alloc] initWithString:@"123"];
    NSMutableString *mStr1 = [mStr copy];
    NSLog(@"%p %p",mStr,mStr1);
    //打印结果
    0x10b549068 0x10b549068
    0x61000007c680 0xa000000003332313

copy:NSString为浅复制,NSMutableString为深复制

    NSString *str = @"abc";
    NSString *str1 = [str mutableCopy];
    NSLog(@"%p %p",str,str1);

    NSMutableString *mStr = [[NSMutableString alloc] initWithString:@"123"];
    NSMutableString *mStr1 = [mStr mutableCopy];
    NSLog(@"%p %p",mStr,mStr1);
    //打印结果
    0x1077e9078 0x6100000778c0
    0x610000077bc0 0x610000077c00

mutableCopy:NSString , NSMutableString均为深复制

NSString对象copy得到NSString对象
NSMutableString对象copy得到NSString对象

NSArray和NSMutableArray
  NSArray *oldArr = @[@"123",@"234"];
    NSLog(@"数组地址%p",oldArr);
    for (NSString *str in oldArr) {
        NSLog(@"%p",str);
    }
    NSArray *newCopyArr = [oldArr copy];
    NSLog(@"数组地址%p",newCopyArr);
    for (NSString *str in newCopyArr) {
        NSLog(@"%p",str);
    }
    NSMutableArray *newMutableCopyArr = [oldArr mutableCopy];
    NSLog(@"数组地址%p",newMutableCopyArr);
    for (NSString *str in newMutableCopyArr) {
        NSLog(@"%p",str);
    }
    //打印结果
数组地址0x60000003f140
0x10a858098
 0x10a8580b8
 数组地址0x60000003f140
0x10a858098
 0x10a8580b8
 数组地址0x61800004b940
 0x10a858098
 0x10a8580b8

由此可以知道,NSArray对象调用mutableCopy会重新新的可变数组对象,但是可变数组对象的元素并没有独立的内存空间,只是地址的复制而已,因此只是对数组进行了深拷贝,而对数组元素却是进行浅拷贝。这种情况叫做集合的单层深复制 (One-Level-Deep Copy)。

经实验,对于集合类型(NSSet/NSMutableSet自然也是一样的),情况和NSArray/NSMutableArray是一样的。

总结:

mutableCopy必定为深复制,复制得到的新对象为可变类型
copy对于不可变类型为浅复制,对于可变类型为深复制,复制后得到的新对象均为不可变类型

你可能感兴趣的:(深copy和浅copy)