1.淺拷貝和深拷貝的區別
淺拷貝只是復制對象本身,對象屬性包含的對象不復制,不產生新對象,直接指向原有對象。
深拷貝復制對象本身,同事屬性也復制,產生新的對象,與原有對象內容相同
2.copy和retain的區別
copy是創建一個新對象,retain是創建一個指針,引用對象計數加1,
copy表示兩個對象內容相同,新對象計數為1,舊對象沒有變化
retain表示兩個對象地址相同(建立一個指針,指針拷貝)
copy是內容拷貝,對于可變數組,屬于深拷貝,計數不變,對于不可變數組,屬于淺拷貝,計數加1。
retain是指針拷貝.屬于淺拷貝,計數加1,不產生新的對象。
例如:
一個NSString 對象地址為0X11111,內容為@"str";
copy到另外一個對象,地址為0x2222,內容為@"str",修改新的對象,對舊對象沒有影響。
retain到另外一個對象,地址相同,同為0x11111
注意:
當NSCopy復制一個不可變數組時,屬于淺拷貝,其余情況屬于深拷貝;
當使用NSMutableCopy時,是深拷貝;
如果自定義類要想實現拷貝動作,必須遵守NSCopy和NSMutableCopy協議。
如果拷貝的是NSObject對象,需要重寫:
-(id)copyWithZone:(NSZone *)zone
-(id)mutableCopyWithZone:(NSZone *)zone
3.深拷貝和淺拷貝的本質區別
是對象或者對象的屬性地址是否一樣,如果一樣則為淺拷貝,不一樣為深拷貝。
Foundation支持復制的類,默認為淺拷貝。
深拷貝拷貝出來的對象與源對象地址不一樣,修改拷貝對象不影響源對象
淺拷貝拷貝出來的對象與源對象地址一樣,修改拷貝對象會影響到源對象
copy就是復制了一個imutable(不可改變)的對象,
mutablecopy就是復制了一個mutable(可變的)的對象
4.NSMutableCopy、NScopy
如果是NSMutableCopy時,無論對象是否可變,副本是可以變的。
如果是NSCopy時,如果是可變對象,副本對象是不可變的。
如果自定義一個copy,那么必須遵守NSCopying并且實現copyWithZone:方法
//mutableCopy拷貝出來的對象為NSMutableString ,NSMutableArray,NSMutableDictionary
//copy拷貝出來的對象為NSString,NSArray,NSDictionary,
5.什么時候用淺拷貝和深拷貝?
淺拷貝是要復制一個對象的指針
深拷貝是將一個對象可變轉為不可變,或是將一個對象不可變轉為可變,或將對象的內容克隆一份。
6.示例
示例1:
//copy返回不可變對象,mutablecopy返回可變對象
NSArray* arrayValue= [NSArray arrayWithObjects:@"1",@"2",@"3", nil];
NSArray* arrayCopy = [arrayValue copy];
NSLog(@"array:%p,arrayCopy:%p",arrayValue,arrayCopy);
//array:0x608000241cb0,arrayCopy:0x608000241cb0
NSMutableArray *marray = [arrayValue mutableCopy];
[marray addObject:@"de"];
[marray removeObjectAtIndex:0];
NSLog(@"arrayValue:%@,marray:%@",arrayValue,marray);
//arrayValue:(1,2,3) marray:(2,3,de)
//copy指針拷貝,mutableCopy拷貝一個新的副本,對原來的沒有影響
示例2:
/**************************copy/mutableCopy NSObject**************************/? ? ViewController *vc = [[ViewController alloc]init];? ? vc.name = @"HelloWorld";? ? ViewController *vcCopy = [vc copy];//沒有重寫-(id)copyWithZone:(NSZone *)zone這個方法分配空間會閃退? ? NSLog(@"vc:%@,copy:%@",vc,vcCopy);//vc:,copy:NSLog(@"vcName:%@,copyName:%@",vc.name,vcCopy.name);? ? //深拷貝? ? ? ? ViewController *vcMutableCopy= [vc mutableCopy];//沒有重寫-(id)mutableCopyWithZone:(NSZone *)zone這個方法申請空間會閃退? ? NSLog(@"vc:%@,mutableCopy:%@",vc,vcMutableCopy);//vc:,mutableCopy:NSLog(@"vcName:%@,MutablecopyName:%@",vc.name,vcMutableCopy.name);
7.結論
//結論:mutableCopy拷貝出來的對象為NSMutableString ,NSMutableArray,NSMutableDictionary
//不可變對象copy拷貝出來的對象為NSString,NSArray,NSDictionary,地址拷貝,
//可變對象copy拷貝出來的對象為不可變對象
? ? ? ? ? ? ? ? ? ? ? ? ?//? ? NSMutableArray *marray = [arrayValue copy];//error
? ? ? ? ? ? ? ? ? ? ? ? ? ?NSMutableString *NMstrCopy= [nmstr copy];
? ? ? ? ? ? ? ? ? ? ? //? ? [NMstrCopy appendString:@"123"];//error
//不可變對象mutablecopy拷貝出來為不可變對象
NSString* strMutableHello =[strSourceHello mutableCopy];//地址不同,內容相同