iOS - Copy 與 MutableCopy

參考鏈接


一、深拷貝和淺拷貝####

  • 深拷貝:對象拷貝 - 直接拷貝內(nèi)容。
  • 單層深拷貝:這種方式只能夠提供一層內(nèi)存拷貝(one-level-deep copy),并非真正的深拷貝。
  • 淺拷貝:指針拷貝 - 將指針中的地址值拷貝一份。

二、對于非集合對象 Copy 與 mutableCopy 的實踐#####
  • 思路:我用四個方案來驗證 Copy 與 mutableCopy 的區(qū)別。
  • 方案:
    • 方案一:copy不可變的字符串
NSString*str = @"aaa";
NSString*copyStr = [str copy];
NSLog(@"str = %p copyStr= %p",str,copyStr);
NSLog(@"指針地址:str = %p copyStr= %p",&str,&copyStr);

輸出結(jié)果:str = 0x104d94068 copyStr= 0x104d94068
指針地址:str = 0x7fff529e9aa8 copyStr= 0x7fff529e9aa0
小結(jié):對不可變的字符串的copy,我們對象的內(nèi)存地址沒有改變,只是指針的地址改變了,所以在這里我們默認(rèn)進(jìn)行了一次淺拷貝,只拷貝了指針。

- 方案二:`copy可變的字符串`
NSMutableString*str1 = [NSMutableString stringWithFormat:@"bbb"];
NSString*copyStr1 = [str1 copy];
NSLog(@"str1 = %p copyStr1 = %p",str1,copyStr1);
NSLog(@"str1 = %p copyStr1= %p",&str1,&copyStr1);

輸出結(jié)果:str1 = 0x7fa522712cd0 copyStr1 = 0x7fa522717ba0
指針地址:str1 = 0x7fff529e9a98 copyStr1= 0x7fff529e9a90
小結(jié):對可變字符串的copy,我們默認(rèn)進(jìn)行了一次深拷貝,直接拷貝了對象。
- 方案三:mutableCopy不可變字符串的

NSString*str2 = @"ccc";
NSMutableString *copyStr2 = [str2 mutableCopy];
NSLog(@"str2 = %p copyStr2 = %p",str2,copyStr2);

輸出結(jié)果:str2 = 0x10d216108 copyStr2 = 0x7fa522726290
小結(jié):對于不可變字符串的mutableCopy我們默認(rèn)進(jìn)行了深拷貝。
- 方案四:mutableCopy可變字符串

NSMutableString*str3 = [NSMutableString stringWithFormat:@"ddd"];
NSMutableString*copyStr3 = [str3 mutableCopy];
NSLog(@"str3 = %p copyStr3 = %p",str3,copyStr3);

輸出結(jié)果:str3 = 0x7fa5227153c0 copyStr3 = 0x7fa5227263f0
小結(jié):對于可變字符串的mutableCopy我們默認(rèn)進(jìn)行了深拷貝。


三、對于集合對象采用 Copy 和 MutableCopy 的實踐

  • 對集合對象采用 Copy 和 mutableCopy 來進(jìn)行實踐
NSArray * arr = @[@"1",@"2",@"3"];
NSMutableArray * mutableArr = [arr mutableCopy];
NSArray * copyArr = [arr copy];
NSMutableArray * newArr = [NSMutableArray arrayWithObjects:@"3",@"2",@"1", nil];
NSArray * newCopyArr = [newArr copy];
NSMutableArray * newMutableCopyArr = [newArr mutableCopy];
//測試 arr 的 copy 和 mutableCopy
NSString * str = [arr firstObject];
NSString * copyStr = [copyArr firstObject];
NSString * mutableStr = [mutableArr firstObject];
//測試 mutableArr 的 copy 和 mutableCopy
NSString * str = [newArr firstObject];
NSString * newCopyStr = [newCopyArr firstObject];
NSString * newMutableCopyStr = [newMutableCopyArr firstObject];
圖3-1.png

圖 3-2.png

圖3-3.png
  • 通過圖 3-1 可以見到,對于不可變的 arr 如果進(jìn)行 copy 的話會進(jìn)行淺拷貝,如果 mutableCopy 會進(jìn)行內(nèi)容拷貝。但是,通過圖 3-2 打印出的地址信息,這里的內(nèi)容拷貝僅僅是拷貝 array 這個對象,array 集合內(nèi)的元素仍然是指針拷貝。所以可以定義為是單層深拷貝。
  • 通過圖 3-3 可以看出,對于可變的集合元素的 copy 與 mutableCopy 都是單層深復(fù)制。

四、結(jié)論####

  • 對于非集合對象
    • copy:因為copy默認(rèn)返回的是不可變的,所以當(dāng)我們對一個不可變的字符串進(jìn)行copy的時候,我們只是拷貝了它的指針(淺拷貝)。當(dāng)我們對一個可變的字符串進(jìn)行拷貝的時候,因為類型轉(zhuǎn)變了,我們需對其進(jìn)行深拷貝。
    • mutableCopy:默認(rèn)返回的是一個可變的對象,適用于可變的對象,例如NSMutableString,NSMutableArray,NSMutableDictionary、etc。 無論對于可變的字符串還是不可變的字符串進(jìn)行mutableCopy,系統(tǒng)都默認(rèn)進(jìn)行深拷貝,那么為什么對于相同類型的進(jìn)行mutableCopy返回的仍然是新的對象呢,因為在這里系統(tǒng)要保證,舊的對象和新的對象都是可變的,切他們之前不會相互影響。
  • 對于集合對象
    • 對于不可變的集合對象,copy 是淺拷貝,mutableCopy 是單層深拷貝。
    • 對于可變的集合對象,無論 copy 或者 mutableCopy 都是單層深拷貝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、對象拷貝有兩種方式:淺復(fù)制和深復(fù)制。顧名思義,淺復(fù)制,并不拷貝對象本身,僅僅是拷貝指向?qū)ο蟮闹羔?;深?fù)制是直接...
    滴答大閱讀 851評論 0 2
  • 前言 不敢說覆蓋OC中所有copy的知識點,但最起碼是目前最全的最新的一篇關(guān)于 copy的技術(shù)文檔了。后續(xù)發(fā)現(xiàn)有新...
    zyydeveloper閱讀 3,710評論 4 35
  • 概念 在Objective-C中并不是所有的對象都支持Copy,MutableCopy,遵守NSCopying協(xié)議...
    LeoAu閱讀 9,162評論 10 28
  • 15號學(xué)習(xí)怎么組裝蛋糕 ps:蛋糕胚是韓國米糕 老板娘給我拍的美美的照片,連自己都認(rèn)不出來啦。???♂? 晚上和學(xué)妹...
    千雨小花閱讀 494評論 0 0
  • ack是tcp的一種確認(rèn)機(jī)制。tcp是一種可靠傳輸?shù)膮f(xié)議,怎么個可靠法則,就是不管你發(fā)送還是接收都要求對方確認(rèn),長...
    郭青耀閱讀 184評論 0 0

友情鏈接更多精彩內(nèi)容