什么是浅拷贝和深拷贝?
浅拷贝是拷贝了指向对象的指针, 深拷贝不但拷贝了对象的指针,还在系统中再分配一块内存,存放拷贝对象的内容。
如何判断浅拷贝和深拷贝?
深浅拷贝取决于拷贝后的对象的是不是和被拷贝对象的地址相同,如果不同,则产生了新的对象,则执行的是深拷贝,如果相同,则只是指针拷贝,相当于retain一次原对象, 执行的是浅拷贝。
举个栗子:
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里的元素是浅拷贝。
本人技术有限,如有错误的地方,欢迎指正。