做网站的公司为什么人少了,wordpress手机排版,优斗网站建设,迎泽网站建设一、概念与总结 1、浅拷贝 浅拷贝就是对内存地址的复制#xff0c;让目标对象指针和源对象指向同一片内存空间#xff0c;当内存销毁的时候#xff0c;指向这片内存的几个指针需要重新定义才可以使用#xff0c;要不然会成为野指针。 浅拷贝就是拷贝指向原来对象的指针让目标对象指针和源对象指向同一片内存空间当内存销毁的时候指向这片内存的几个指针需要重新定义才可以使用要不然会成为野指针。 浅拷贝就是拷贝指向原来对象的指针使原对象的引用计数1可以理解为创建了一个指向原对象的新指针而已并没有创建一个全新的对象。 2、深拷贝 深拷贝是指拷贝对象的具体内容而内存地址是自主分配的拷贝结束之后两个对象虽然存的值是相同的但是内存地址不一样两个对象也互不影响互不干涉。 深拷贝就是拷贝出和原来仅仅是值一样但是内存地址完全不一样的新的对象创建后和原对象没有任何关系。 3、总结 深拷贝就是内容拷贝浅拷贝就是指针拷贝。本质区别在于 是否开启新的内存地址是否影响内存地址的引用计数 二、示例分析 在iOS中深拷贝与浅拷贝要更加的复杂涉及到容器与非容器、可变与不可变对象的copy与mutableCopy。下面用示例逐一分析 1、非集合对象的copy与mutableCopy 1.1 不可变对象NSString - (void) noMutableNSStringTest
{NSString *str1 test001;NSMutableString *str2 [str1 copy];//copy返回的是不可变对象str2不能被修改因此会发生崩溃//[str2 appendString:test];NSMutableString *str3 [str1 mutableCopy];[str3 appendString:modify];NSLog(str1:%p - % \r\n,str1,str1);NSLog(str2:%p - % \r\n,str2,str2);NSLog(str3:%p - % \r\n,str3,str3);
} 打印结果 2017-07-20 18:02:10.642 beck.wang[1306:169414] str1:0x106abdbd0 - test001
2017-07-20 18:02:10.643 beck.wang[1306:169414] str2:0x106abdbd0 - test001
2017-07-20 18:02:10.643 beck.wang[1306:169414] str3:0x608000260940 - test001modify 分析str1、str2地址相同并且与str3地址不同NSString的copy是浅拷贝且copy返回的对象是不可变对象mutableCopy是深拷贝。 1.2 可变对象NSMutableString - (void) mutableNSStringTest
{NSMutableString *mstr1 [NSMutableString stringWithString:test002];NSMutableString *mstr2 [mstr1 copy];//copy返回的是不可变对象mstr2不能被修改因此会发生崩溃//[str2 appendString:test];NSMutableString *mstr3 [mstr1 mutableCopy];[mstr3 appendString:modify];NSLog(mstr1:%p - % \r\n,mstr1,mstr1);NSLog(mstr2:%p - % \r\n,mstr2,mstr2);NSLog(mstr3:%p - % \r\n,mstr3,mstr3);
} 打印结果 2017-07-20 18:14:35.789 beck.wang[1433:180881] mstr1:0x610000075e40 - test002
2017-07-20 18:14:35.790 beck.wang[1433:180881] mstr2:0xa323030747365747 - test002
2017-07-20 18:14:35.790 beck.wang[1433:180881] mstr3:0x610000074480 - test002modify 分析mstr1、mstr2、mstr3 地址都不同NSMutableString对象copy与mutableCopy都是深拷贝且copy返回的对象是不可变对象。 2、集合对象的copy与mutableCopy 2.1 不可变对象NSArray - (void) mutableNSArrayTest
{NSArray *arry1 [[NSArray alloc] initWithObjects:value1, value2,nil];NSArray *arry2 [arry1 copy];NSArray *arry3 [arry1 mutableCopy];NSLog(arry1:%p - % \r\n,arry1,arry1);NSLog(arry2:%p - % \r\n,arry2,arry2);NSLog(arry3:%p - % \r\n,arry3,arry3);
} 打印结果 2017-07-20 18:33:53.707 beck.wang[1502:194476] arry1:0x60800003b480 - (value1,value2
)
2017-07-20 18:33:53.708 beck.wang[1502:194476] arry2:0x60800003b480 - (value1,value2
)
2017-07-20 18:33:53.708 beck.wang[1502:194476] arry3:0x60800004cd20 - (value1,value2
) 分析arry1、arry2 地址一样arr3 地址不一样NSArray的copy是浅拷贝且copy返回的对象是不可变对象mutableCopy是深拷贝。 2.2 可变对象NSMutableArray - (void) NSMutableArrayTest
{NSMutableArray *marry1 [[NSMutableArray alloc] initWithObjects:value1, value2,nil];NSMutableArray *marry2 [marry1 copy];//copy返回的是不可变对象marry2不能被修改因此会崩溃//[marry2 addObject:value3];NSMutableArray *marry3 [marry1 mutableCopy];NSLog(marry1:%p - % \r\n,marry1,marry1);NSLog(marry2:%p - % \r\n,marry2,marry2);NSLog(marry3:%p - % \r\n,marry3,marry3);
} 打印结果 2017-07-20 18:55:43.243 beck.wang[1577:204641] marry1:0x600000048d60 - (value1,value2
)
2017-07-20 18:55:43.244 beck.wang[1577:204641] marry2:0x600000026000 - (value1,value2
)
2017-07-20 18:55:43.244 beck.wang[1577:204641] marry3:0x6000000494b0 - (value1,value2
) 分析marry1、marry2、marr3 地址都不一样NSMutableArray对象copy与mutableCopy都是深拷贝且copy返回的对象是不可变对象。 特别注意的是对于集合类的可变对象来说深拷贝并非严格意义上的深复制只能算是单层深复制即虽然新开辟了内存地址但是存放在内存上的值也就是数组里的元素仍然之乡员数组元素值并没有另外复制一份这就叫做单层深复制。 举例说明 - (void)singleNSMutableArrayTest
{NSMutableArray *marry1 [[NSMutableArray alloc] init];NSMutableString *mstr1 [[NSMutableString alloc]initWithString:value1];NSMutableString *mstr2 [[NSMutableString alloc]initWithString:value2];[marry1 addObject:mstr1];[marry1 addObject:mstr2];NSMutableArray *marry2 [marry1 copy];NSMutableArray *marry3 [marry1 mutableCopy];NSLog(marry1:%p - % \r\n,marry1,marry1);NSLog(marry2:%p - % \r\n,marry2,marry2);NSLog(marry3:%p - % \r\n,marry3,marry3);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry1[0],marry1[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry2[0],marry2[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry3[0],marry3[1]);NSLog(\r\n------------------修改原值后------------------------\r\n);[mstr1 appendFormat:aaa];NSLog(marry1:%p - % \r\n,marry1,marry1);NSLog(marry2:%p - % \r\n,marry2,marry2);NSLog(marry3:%p - % \r\n,marry3,marry3);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry1[0],marry1[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry2[0],marry2[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry3[0],marry3[1]);
} 打印结果 2017-07-20 19:48:24.539 beck.wang[1750:230132] marry1:0x60800004ae00 - (value1,value2
)
2017-07-20 19:48:24.539 beck.wang[1750:230132] marry2:0x608000023f00 - (value1,value2
)
2017-07-20 19:48:24.539 beck.wang[1750:230132] marry3:0x60800004abc0 - (value1,value2
)
2017-07-20 19:48:24.540 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40
2017-07-20 19:48:24.540 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40
2017-07-20 19:48:24.540 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40
2017-07-20 19:48:24.540 beck.wang[1750:230132]
------------------修改原值后------------------------
2017-07-20 19:48:24.540 beck.wang[1750:230132] marry1:0x60800004ae00 - (value1aaa,value2
)
2017-07-20 19:48:24.540 beck.wang[1750:230132] marry2:0x608000023f00 - (value1aaa,value2
)
2017-07-20 19:48:24.540 beck.wang[1750:230132] marry3:0x60800004abc0 - (value1aaa,value2
)
2017-07-20 19:48:24.541 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40
2017-07-20 19:48:24.541 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40
2017-07-20 19:48:24.541 beck.wang[1750:230132] 数组元素地址:value1:0x60800006df40 - value2:0x60800006cb40 分析在修改原值之前marry1、marry2、marr3 地址都不一样很明显copy和mutableCopy都是深拷贝但是从修改原值后的打印结果来看这里的深拷贝只是单层深拷贝新开辟了内存地址但是数组中的值还是指向原数组的这样才能在修改原值后marry2 marr3中的值都修改了。另外从打印的数组元素地址可以很明显的看出来修改前后marry1、marry、marr3的数组元素地址都是一模一样的更加佐证了这一点。 2.3 思维扩展集合对象的完全深拷贝 2.2中提到了集合类的对象来说深拷贝只是单层深拷贝那有没有办法实现每一层都深拷贝呢回答是肯定的目前我们可以这么做 1归档解档大法 - (void) deplyFullCopy
{NSMutableArray *marry1 [[NSMutableArray alloc] init];NSMutableString *mstr1 [[NSMutableString alloc]initWithString:value1];NSMutableString *mstr2 [[NSMutableString alloc]initWithString:value2];[marry1 addObject:mstr1];[marry1 addObject:mstr2];NSData *data [NSKeyedArchiver archivedDataWithRootObject:marry1];NSArray *marray2 [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];NSLog(marry1:%p - % \r\n,marry1,marry1);NSLog(marry2:%p - % \r\n,marray2,marray2);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry1[0],marry1[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marray2[0],marray2[1]);
} 打印结果 2017-07-20 20:04:38.726 beck.wang[1833:242158] marry1:0x600000048a00 - (value1,value2
)
2017-07-20 20:04:38.726 beck.wang[1833:242158] marry2:0x600000049780 - (value1,value2
)
2017-07-20 20:04:38.726 beck.wang[1833:242158] 数组元素地址:value1:0x600000066300 - value2:0x600000067000
2017-07-20 20:04:38.726 beck.wang[1833:242158] 数组元素地址:value1:0x600000066740 - value2:0x600000066f40 分析我们可以看到开辟了新的内存地址的同时数组元素的指针地址也不同了实现了完全的深拷贝。 2- (instancetype)initWithArray:(NSArrayObjectType *)array copyItems:(BOOL)flag; - (void) deplyFullCopy2
{NSMutableArray *marry1 [[NSMutableArray alloc] init];NSMutableString *mstr1 [[NSMutableString alloc]initWithString:value1];NSMutableString *mstr2 [[NSMutableString alloc]initWithString:value2];[marry1 addObject:mstr1];[marry1 addObject:mstr2];NSArray *marray2 [[NSArray alloc] initWithArray:marry1 copyItems:YES];NSLog(marry1:%p - % \r\n,marry1,marry1);NSLog(marry2:%p - % \r\n,marray2,marray2);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marry1[0],marry1[1]);NSLog(数组元素地址:value1:%p - value2:%p \r\n,marray2[0],marray2[1]);
} 打印结果 2017-07-20 20:08:04.201 beck.wang[1868:246161] marry1:0x610000050320 - (value1,value2
)
2017-07-20 20:08:04.202 beck.wang[1868:246161] marry2:0x6100002214c0 - (value1,value2
)
2017-07-20 20:08:04.202 beck.wang[1868:246161] 数组元素地址:value1:0x610000265600 - value2:0x610000266400
2017-07-20 20:08:04.202 beck.wang[1868:246161] 数组元素地址:value1:0xa003165756c61766 - value2:0xa003265756c61766 分析同上。 三、准则 No1可变对象的copy和mutableCopy方法都是深拷贝区别完全深拷贝与单层深拷贝 。 No2不可变对象的copy方法是浅拷贝mutableCopy方法是深拷贝。 No3copy方法返回的对象都是不可变对象。 万语千言汇成一张图 更多http://www.cnblogs.com/beckwang0912/p/7212075.html转载于:https://www.cnblogs.com/tlios/p/7645574.html