關于Copy的深度解析

其實也不算深度解析啦,主要是題目要響亮一點大家才有看的欲望嘛!?。?/p>

首先關于Copy想必在面試題中大家見過很多,下面我就寫一下我對Copy的理解。

1.Copy是什么???

copy和mutableCopy是方法,是NSObject內定義的方法。

2.Copy有什么用???

copy顧名思義就是拷貝或者說克隆,所以copy的目的就是復制一份原來的內容,進一步思考為什么需要拷貝?顯然:拷貝的目的就是改變原來的內容不影響副本,改變副本也不影響原來的內容。

3.從NSString,NSMutableString,NSArray,NSMutableArray說明深拷貝和淺拷貝的區別

首先大家來想一下為什么要用到Copy??Copy的目的所在是什么?為什么需要生成一個新的對象呢???

Copy是為了互不干擾,生成兩個對象是為了相互改變的時候不影響另外一個對象。

其次大家要牢記一點,使用Copy方法得到的是不可變對象,使用mutableCopy方法得到的必須是可變對象。

一.NSString、NSMutableString非容器對象分析

1.不可變字符串的copy和mutableCopy

NSString *str = @"xiaoming";

NSString *str1 = [str copy];

NSMutableString * str2 = [str mutableCopy];

NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",str,str,NSStringFromClass([str class]),str1,str1,NSStringFromClass([str1 class]),str2,str2,NSStringFromClass([str2 class]));

打印結果如下:

----str:0x10c8e4068,xiaoming,__NSCFConstantString----str1:0x10c8e4068,xiaoming,__NSCFConstantString----str2:0x608000266ac0,xiaoming,__NSCFString

通過上面的打印結果大家可以看到不可變的字符串經過copy之后沒有生成對象,得到的是不可變字符串,經過mutableCopy之后生成了新的對象,得到是可變字符串。

為什么copy沒有得到對象呢???因為原來的對象是不可以修改的,新拷貝的對象也是不可修改的,所以不會影響到另外一個對象。已經符合拷貝的目的 了,所以,OC為了對內存進行優化, 就不會生成一個新的對象。

為什么mutableCopy會生成新的對象呢?生成的是一個可變對象,這樣兩個對象其中一個對象改變而不影響另外一個對象。

2.可變字符串的copy和mutableCopy

NSMutableString *mulStr = [NSMutableString stringWithFormat:@"abc"];

NSString *mulStr1 = [mulStr copy];

NSMutableString * mulStr2 = [mulStr mutableCopy];

NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",mulStr,mulStr,NSStringFromClass([mulStr class]),mulStr1,mulStr1,NSStringFromClass([mulStr1 class]),mulStr2,mulStr2,NSStringFromClass([mulStr2 class]));

打印結果如下:

----str:0x600000260180,abc,__NSCFString----str1:0xa000000006362613,abc,NSTaggedPointerString----str2:0x6000002601c0,abc,__NSCFString

通過上面的打印結果可以看出來可變字符串經過copy和mutableCopy之后都創建了新的對象。經過copy之后得到的是不可變字符串,經過mutableCopy之后 得到的是可變字符串。

為什么都會生成對象呢???因為可變字符串本來就是可以改變的,為了改變互不干擾,從而生成新的對象,符合拷貝的目的。

二:NSArray、NSMutableArray容器對象分析

首先容器對象和非容器對象一樣同樣遵從下面的總結:

如果對一不可變對象復制,copy是指針復制(淺拷貝)、mutableCopy就是對象復制(深拷貝)。

如果是對可變對象復制,都是深拷貝,但是copy返回的對象是不可變的。

1.NSArray的copy和mutableCopy?

NSArray *array = [[NSArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"a"],@"b",@"c", nil];

NSArray *array1 = [array copy];

NSMutableArray *array2 = [array mutableCopy];

// NSArray *array3 = [array mutableCopy];

NSArray *array3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];

NSLog(@"----array:%p,----array1:%p,-----array2:%p,----array3:%p",array,array1,array2,array3);

NSMutableString *str1 = [array objectAtIndex:0];

[str1 appendString:@"hahhaha"];

[array2 insertObject:@"111111" atIndex:0];

NSMutableString *str2 = [array2 objectAtIndex:1];

[str2 appendString:@"111111"];

NSLog(@"----array:%@,----array1:%@,-----array2:%@,----array3:%@",array,array1,array2,array3);

打印結果如下:

?----array:0x608000242070,----array1:0x608000242070,-----array2:0x608000242b50,----array3:0x608000242d90

?----array:(

ahahhaha111111,

b,

c

),----array1:(

ahahhaha111111,

b,

c

),-----array2:(

111111,

ahahhaha111111,

b,

c

),----array3:(

a,

b,

c

)

通過上面的打印可以看出來NSArray 經過Copy之后沒有創建對象,經過mutableCopy之后創建了新的對象,具體原因和NSString一樣,但是里面的元素對象還是指針拷貝,要想做到對象拷貝,可以使用歸檔的方法。

2.NSMutableArray 的copy和MutableCopy

NSMutableArray *mulArray = [[NSMutableArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"abc"],@"def", nil];

NSMutableArray *mulArray1 = [mulArray copy];

NSMutableArray *mulArray2 = [mulArray mutableCopy];

NSLog(@"----array:%p,----arrar1:%p,----array2:%p",mulArray,mulArray1,mulArray2);

NSMutableString *mulstr = [mulArray objectAtIndex:0];

[mulstr appendString:@"abc"];

NSLog(@"----array:%@,-----array1:%@,-----array2:%@",mulArray,mulArray1,mulArray2);

NSLog(@"----array:%@,-----array1:%@,-----array2:%@",NSStringFromClass([mulArray class]) ,NSStringFromClass([mulArray1 class]),NSStringFromClass([mulArray2 class]));

打印結果如下:

----array:0x60000005af40,----arrar1:0x60000002b1a0,----array2:0x60000005ad60

----array:(

abcabc,

def

),-----array1:(

abcabc,

def

),-----array2:(

abcabc,

def

)

通過上面的打印可以看出來NSArray 經過Copy和mutableCopy之后都創建新的對象,具體原因和NSString一樣,但是里面的元素對象還是指針拷貝,要想做到對象拷貝,可以使用歸檔的方法。

但是大家還要牢記一點:NSMutableArray多次copy每次都會新建對象而NSArray多次copy只新建一次對象。

4.總結

正是因為調用copy方法有時候會生成一個新的對象, 有時候不會生成一個新的對象所以:

如果沒有生成新的對象, 我們稱之為淺拷貝, 本質就是指針拷貝

如果生成了新的對象, 我們稱之為深拷貝, 本質就是會創建一個新的對象

最后:最重要的還是記住拷貝的目的,這樣理解深淺拷貝都會變得非常簡單,改變原來的內容不影響副本,改變副本也不影響原來的內容

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容