前言:
提到iOS中的淺復制和深復制的區別,大家都知道淺復制過來的是對象的地址,而深復制,相當于重新開辟了內存空間,存儲這個對象。
用代碼說話
①單個對象的淺復制與深復制
/// 單個對象 淺復制、深賦值
- (void)ordinaryCopyVSMutableCopy {
NSString *str = @"hehe";
NSLog(@"源字符:%p",str);
//淺
NSString *cStr = [str copy];
NSLog(@"淺復制: Cstr = %p",cStr);
NSString *temp = [str copyWithZone:nil];
NSLog(@"copyWithZone: temp = %p",temp);
//深
NSString *mStr = [str mutableCopy];
NSLog(@"深復制: mStr = %p",mStr);
}
輸出結果:
單個對象深淺復制輸出結果.png
tips:可以看到
copy
、copyWithZone
方法都是淺復制,對象的地址并沒有改變,而mutableCopy
重新開辟了內存控件,是深復制
數組及集合類對象的淺復制、深復制、完全復制
我們先定義一個原始數組
NSArray *originArr = [NSArray arrayWithObjects:@"1",@"2", nil];
NSLog(@"原數組 地址:%p",originArr);
NSLog(@"原數組中對象的地址: %p,%p \n",originArr[0],originArr[1]);
看代碼:
①對數組進行淺復制
//對數組進行淺復制
NSArray *copyArr = [originArr copy];
NSLog(@"淺復制 地址:%p",copyArr);
NSLog(@"淺復制數組中對象的地址: %p,%p \n",copyArr[0],copyArr[1]);
對比輸出結果看:
數組淺復制結果對比.png
tips:可以看到 不論是數組本身還是數組中的元素,地址都沒有發生變化,這就是完完全全的淺復制
那么問題1:
[NSArray arrayWithArray:originArr]
是淺復制 還是 深復制呢
NSArray *arr = [NSArray arrayWithArray:originArr];
NSLog(@"arrayWithArray深復制 地址:%p",arr);
NSLog(@"arrayWithArray深復制數組中對象的地址: %p,%p \n",arr[0],arr[1]);
結果:
arrayWithArray結果.png
tips:
arr
相比于源數組,算是一次深復制,但是數組中的元素地址依舊沒有發生變化
②對數組進行深復制
NSArray *mCopyArr = [originArr mutableCopy];
NSLog(@"深復制 地址:%p",mCopyArr);
NSLog(@"深復制數組中對象的地址: %p,%p \n",mCopyArr[0],mCopyArr[1]);
打印地址發現:
數組深復制.png
可以發現
mCopyArr
相比于原先的數組算是深復制了,但是內部的元素依舊是原先數組中的元素
問題2:[[NSArray alloc] initWithArray:.... copyItems:true]
是淺復制 還是 深復制呢
NSArray *array = [[NSArray alloc] initWithObjects:[[NSMutableString alloc] initWithString:@"1"], @"2",nil];
NSLog(@"array 地址: %p",array);
NSLog(@"array中元素的地址 :%p,%p",array[0],array[1]);
NSArray *arrWithCopyItem = [[NSArray alloc] initWithArray:array copyItems:true];
NSLog(@"arrWithCopyItem深復制 地址:%p",arrWithCopyItem);
NSLog(@"arrWithCopyItem深復制數組中對象的地址: %p,%p \n",arrWithCopyItem[0],arrWithCopyItem[1]);
輸出結果:
copyItems深復制、淺復制測試.png
可以看到,
arrWithCopyItem
對于源數組array
中的可變對象進行的是深復制,對不可變對象做的是淺復制,所以可以稱,[[NSArray alloc] initWithArray:.... copyItems:true]
方法是與源數組做了一次不完全的深復制,對于其中的不可變對象依舊是淺復制tips:字典的
[NSDictionary alloc] initWithDictionary:... copyItems:..
這個方法結果同上
問題來了:這不算真正意義上的深復制,即完全復制,那用什么方法可以實現完全復制呢?
②對數組進行完全復制
方法有很多種,這里簡單介紹兩種:
一:歸檔、解擋操作
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:originArr];
NSData *aData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSArray *mmCopyArr = (NSArray *)aData;
NSLog(@"①歸檔深復制 地址:%p",mmCopyArr);
NSLog(@"①歸檔深復制數組中對象的地址: %p,%p \n",mmCopyArr[0],mmCopyArr[1]);
源數組.png
歸檔、解檔后.png
可以看到,不僅數組本身為深復制,數組中的元素也都重新開辟了內存空間
二:對數組進行遍歷深復制,該方法較為簡單,就不寫代碼了