iOS日记-浅拷贝和深拷贝

什么是浅拷贝和深拷贝?

浅拷贝是拷贝了指向对象的指针, 深拷贝不但拷贝了对象的指针,还在系统中再分配一块内存,存放拷贝对象的内容。

如何判断浅拷贝和深拷贝?

深浅拷贝取决于拷贝后的对象的是不是和被拷贝对象的地址相同,如果不同,则产生了新的对象,则执行的是深拷贝,如果相同,则只是指针拷贝,相当于retain一次原对象, 执行的是浅拷贝。

举个栗子:


iOS日记-浅拷贝和深拷贝_第1张图片
1118933-20170720203748536-592203434.png

NSString

copy

    id str = @"123";
    id strT = [str copy];
    NSLog(@"str是%p", str);
    NSLog(@"strT是%p", strT);

打印结果:

2019-03-15 14:37:48.718655+0800 TestDemo[4924:163493] str是0x109a14188
2019-03-15 14:37:48.718848+0800 TestDemo[4924:163493] strT是0x109a14188

可以看到str和strT内存地址相同,所以是浅拷贝。

mutableCopy

id str = @"123";
id strMT = [str mutableCopy];
NSLog(@"str是%p", str);
NSLog(@"strMT是%p", strMT);

打印结果:

2019-03-15 14:42:31.396609+0800 TestDemo[4994:165491] str是0x103e15188
2019-03-15 14:42:31.396796+0800 TestDemo[4994:165491] strMT是0x600003504660

str和strMT内存地址不相同,所以分配了一个新的内存地址,深拷贝。

NSMutableString

copy

id str = [NSMutableString stringWithString:@"123"];
id strT = [str copy];
NSLog(@"str是%p", str);
NSLog(@"strT是%p", strT);

打印结果:

2019-03-15 14:52:18.518225+0800 TestDemo[5091:168555] str是0x600003a91260
2019-03-15 14:52:18.518462+0800 TestDemo[5091:168555] strT是0x91ff4d172e4aa37b

可以看到str和strT内存地址不相同,所以是深拷贝。

mutableCopy

id str = [NSMutableString stringWithString:@"123"];
id strMT = [str mutableCopy];
NSLog(@"str是%p", str);
NSLog(@"strMT是%p", strMT);

打印结果:

2019-03-15 14:55:12.743494+0800 TestDemo[5151:170276] str是0x6000005b66a0
2019-03-15 14:55:12.743611+0800 TestDemo[5151:170276] strMT是0x6000005b5ad0

可以看到str和strMT内存地址不相同,所以是深拷贝。

NSArray

copy

    id arr = [NSArray array];
    id arrT = [arr copy];
    NSLog(@"arr是%p", arr);
    NSLog(@"arrT是%p", arrT);

打印结果:

2019-03-15 14:58:06.262624+0800 TestDemo[5211:171791] arr是0x600003be8080
2019-03-15 14:58:06.262764+0800 TestDemo[5211:171791] arrT是0x600003be8080

可以看到arr和arrT内存地址相同,所以是浅拷贝。

mutableCopy

    id arr = [NSArray array];
    id arrMT = [arr mutableCopy];
    NSLog(@"arr是%p", arr);
    NSLog(@"arrMT是%p", arrMT);

打印结果:

2019-03-15 15:00:03.961066+0800 TestDemo[5252:172739] arr是0x6000013e40a0
2019-03-15 15:00:03.961257+0800 TestDemo[5252:172739] arrMT是0x600001f8f990

可以看到arr和arrMT内存地址不相同,所以是深拷贝。

NSMutableArray

copy

    id arr = [NSMutableArray array];
    id arrT = [arr copy];
    NSLog(@"arr是%p", arr);
    NSLog(@"arrT是%p", arrT);

打印结果:

2019-03-15 15:01:57.131225+0800 TestDemo[5295:173860] arr是0x600001c53f60
2019-03-15 15:01:57.131345+0800 TestDemo[5295:173860] arrT是0x60000105c060

可以看到arr和arrT内存地址不相同,所以是深拷贝。

mutableCopy

    id arr = [NSMutableArray array];
    id arrMT = [arr mutableCopy];
    NSLog(@"arr是%p", arr);
    NSLog(@"arrMT是%p", arrMT);

打印结果:

2019-03-15 15:03:51.005760+0800 TestDemo[5332:175037] arr是0x6000018ddbc0
2019-03-15 15:03:51.006076+0800 TestDemo[5332:175037] arrMT是0x6000018dd710

可以看到arr和arrMT内存地址不相同,所以是深拷贝。

NSDictionary和NSMutableDictionary我就不列出来了(偷个懒),感兴趣的同学可以自己试下。

总结以上就是:

  • 不可变对象的copy方法是浅拷贝,mutableCopy方法是深拷贝。
  • 可变对象的copy和mutableCopy方法都是深拷贝。

我这里想到一个问题,如果对一个NSMutableArray进行深拷贝,那么NSMutableArray里的元素是否进行了深拷贝呢?代码见分晓:

    NSMutableArray * arr = [NSMutableArray array];
    NSString * str = @"123";
    [arr addObject:str];
    
    NSArray * arrT = [arr copy];
    NSString * strT = arrT.firstObject;
    
    NSLog(@"arr是%p", arr);
    NSLog(@"str是%p", str);
    NSLog(@"arrT是%p", arrT);
    NSLog(@"strT是%p", strT);

打印结果:

2019-03-15 15:21:45.026257+0800 TestDemo[5540:181659] arr是0x600001aaef10
2019-03-15 15:21:45.026374+0800 TestDemo[5540:181659] str是0x104fc6188
2019-03-15 15:21:45.026472+0800 TestDemo[5540:181659] arrT是0x6000016c0b20
2019-03-15 15:21:45.026558+0800 TestDemo[5540:181659] strT是0x104fc6188

可以看到str和strT的内存地址是一样的,说明NSMutableArray里的元素是浅拷贝。

本人技术有限,如有错误的地方,欢迎指正。

你可能感兴趣的:(iOS日记-浅拷贝和深拷贝)