copy、mutableCopy與淺拷貝丸升、深拷貝

1.先來看一段代碼

    NSArray *array;
    NSMutableArray *arrM = [NSMutableArray arrayWithObjects:@"a",@"b",@"c", nil];
    array = arrM;
    NSLog(@"-----%@",array);
    [arrM addObject:@"d"];
    NSLog(@"=======%@",array);
//輸出結果: 
-----(
    a,
    b,
    c
)
 =======(
    a,
    b,
    c,
    d
)

思考:arrM先賦值給array,再增加d元素,為什么array中卻也加入了新的元素?
這里先分析造成這個情況的原因如下圖:

問題分析一
  • 所以當arrM新增元素時,array中的值也隨之發(fā)生了改變.那么如何解決這種情況呢?讓array中的值不隨arrM的改變而改變?
    解決方式
//造成這種問題的關鍵代碼
//array = arr;
array = [arr copy];

copy方法做了那些事情?起到了什么樣的作用,下面我們仔細研究一下.

2.copy铆农、mutableCopy

  • 首先我們要知道,什么是copy.就像我們將桌面上的一文件進行ctrl+cctrl+v一樣,會根據(jù)之前的文件,生成一個副本文件,副本文件中的內容與源文件中相同.copy與mutableCopy也是一樣的道理,一般情況下,調用對象的copy发钝、mutableCopy會生成一個新的對象,一定要注意這里說的是一般情況下,后面會說明不一般的情況

copy顿涣、mutableCopy的本質:修改原來的對象不能影響到拷貝出來得對象;修改拷貝出來的對象也不能影響到原來的對象,總之就是兩個對象互不影響.

  • 下面以數(shù)組為例,總結一下copy、mutableCopy的具體作用
    • 例一:由一個可變數(shù)組,生成另外一個可變數(shù)組
    NSMutableArray *arrM1 = [NSMutableArray array];
    NSMutableArray *arrM2 = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
    arrM1 = [arrM2 mutableCopy];
    [arrM1 addObject:@"aa"];
    [arrM2 addObject:@"bb"];
    NSLog(@"arrM1 = %@,arrM2 = %@,arrM1內存地址 = %p,arrM2內存地址 = %p",arrM1,arrM2,arrM1,arrM2);
//輸出結果:
arrM1 = (
    1,
    2,
    aa
),arrM2 = (
    1,
    2,
    bb
),arrM1內存地址 = 0x600000242130,arrM2內存地址 = 0x6000002418c0
  • 在內存中的表現(xiàn)形式


    例一圖解
  • 總結:該方式會生成一個新的對象,兩個對象之間互不影響

  • 例二:由一個不可變數(shù)組,生成一個可變數(shù)組

    NSMutableArray *arrM = [NSMutableArray array];
    NSArray *dataArray = @[@"1",@"2"];
    arrM = [dataArray mutableCopy];
    [arrM addObject:@"3"];
    NSLog(@"arrM = %@,dataArray = %@,arrM內存地址 = %p,dataArray內存地址 = %p",arrM,dataArray,arrM,dataArray);
//輸出:
arrM = (
    1,
    2,
    3
),dataArray = (
    1,
    2
),arrM內存地址 = 0x600000055cc0,dataArray內存地址 = 0x600000222b20
  • 總結:該方式會生成一個新的對象,兩個對象之間互不影響,內存中的表現(xiàn)形式與例一相同.

  • 例三:由一個可變數(shù)組,生成一個不可變數(shù)組

    NSArray *dataArray;
    NSMutableArray *arrM = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
    dataArray = [arrM copy];
    [arrM addObject:@"3"];
    NSLog(@"dataArray = %@,arrM = %@,dataArray內存地址 = %p,arrM內存地址 = %p",dataArray,arrM,dataArray,arrM);
//輸出:
dataArray = (
    1,
    2
),arrM = (
    1,
    2,
    3
),dataArray內存地址 = 0x604000220ea0,arrM內存地址 = 0x604000244320
  • 總結:該方式會生成一個新的對象,兩個對象之間互不影響,內存中的表現(xiàn)形式與例一相同.

  • 例四:根據(jù)一個不可變數(shù)組,生成一個不可變數(shù)組.注意:這種情況就是上面說的不一般的情況

    NSArray *arr1;
    NSArray *arr2 = @[@"1",@"2",@"3"];
    arr1 = [arr2 copy];
    NSLog(@"arr1 = %@,arr2 = %@,arr1內存地址 = %p,arr2內存地址 = %p",arr1,arr2,arr1,arr2);
//輸出:
arr1 = (
    1,
    2,
    3
),arr2 = (
    1,
    2,
    3
),arr1內存地址 = 0x60000045df10,arr2內存地址 = 0x60000045df10
例四圖解
  • 總結:該方式會生成一個新的對象,兩個對象之間互不影響

前三個例子都會生成一個新的對象,保證兩個對象之間進行修改,互不影響,但是例四在不生成新對象的情況下,依然能保證兩個對象之間進行修改,互不影響.
原因: 因為原來的對象是不能修改的, 拷貝出來的對象也是不能修改的,既然兩個都不能修改, 所以永遠不能影響到另外一個對象, 那么就滿足了我們上面提到的copy酝豪、mutableCopy的本質,

3.淺拷貝、深拷貝

在調用了copy精堕、mutableCopy方法之后:

  • 如果沒有生成新的對象, 我們稱之為淺拷貝, 本質就是指針拷貝,比如例四.
  • 如果生成了新的對象, 我們稱之為深拷貝, 本質就是會創(chuàng)建一個新的對象.比如例一孵淘、例二、例三.

4.補充

  • 在明白了淺拷貝歹篓、深拷貝之后,我們回到最初的那段代碼
NSArray *array;
    NSMutableArray *arrM = [NSMutableArray arrayWithObjects:@"a",@"b",@"c", nil];
    array = arrM;
    NSLog(@"-----%@",array);
    [arrM addObject:@"d"];
    NSLog(@"=======%@",array);
//輸出結果: 
-----(
    a,
    b,
    c
)
 =======(
    a,
    b,
    c,
    d
)

這里出現(xiàn)這種情況的原因,上面也說過了就是array = arrM;就是這句代碼造成的.而且其效果與淺拷貝相同,就是拷貝了一個指針指向了數(shù)組對象.
所以:=是淺拷貝,大多數(shù)情況下應該是淺拷貝吧.深拷貝的情況沒有注意過,如果寫的不對,請指證,我及時修改.3Q

5.類比Foundation框架中的其他數(shù)據(jù)類型

  • 話不多說直接上圖,沒圖說個吉米巴特勒


    珍藏多年的老圖
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末瘫证,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子庄撮,更是在濱河造成了極大的恐慌背捌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洞斯,死亡現(xiàn)場離奇詭異毡庆,居然都是意外死亡,警方通過查閱死者的電腦和手機烙如,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門么抗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人亚铁,你說我怎么就攤上這事蝇刀。” “怎么了徘溢?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵吞琐,是天一觀的道長。 經常有香客問我然爆,道長站粟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任施蜜,我火速辦了婚禮卒蘸,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己缸沃,他們只是感情好恰起,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趾牧,像睡著了一般检盼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翘单,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天吨枉,我揣著相機與錄音,去河邊找鬼哄芜。 笑死貌亭,一個胖子當著我的面吹牛,可吹牛的內容都是我干的认臊。 我是一名探鬼主播圃庭,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼失晴!你這毒婦竟也來了剧腻?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤涂屁,失蹤者是張志新(化名)和其女友劉穎书在,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拆又,經...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡儒旬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了遏乔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片义矛。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盟萨,靈堂內的尸體忽然破棺而出凉翻,到底是詐尸還是另有隱情,我是刑警寧澤捻激,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布制轰,位于F島的核電站,受9級特大地震影響胞谭,放射性物質發(fā)生泄漏垃杖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一丈屹、第九天 我趴在偏房一處隱蔽的房頂上張望调俘。 院中可真熱鬧伶棒,春花似錦、人聲如沸彩库。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽亭螟。三九已至汁尺,卻和暖如春奸例,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背虑粥。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工恭金, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留项贺,地道東北人鳞仙。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓寇蚊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親繁扎。 傳聞我的和親對象是個殘疾皇子幔荒,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容