淺拷貝和深拷貝的理解

概念

對(duì)象拷貝有兩種方式:淺復(fù)制和深復(fù)制。顧名思義构诚,淺復(fù)制,并不拷貝對(duì)象本身铆惑,僅僅是拷貝指向?qū)ο蟮闹羔樂吨觯簧顝?fù)制是直接拷貝整個(gè)對(duì)象內(nèi)存到另一塊內(nèi)存中。
再簡(jiǎn)單些說(shuō):淺復(fù)制就是指針拷貝员魏;深復(fù)制就是內(nèi)容拷貝丑蛤。

1. 非集合類對(duì)象的copy和mutableCopy

系統(tǒng)非集合類對(duì)象指的是 NSString,NSMutableString撕阎,NSNumber...之類的對(duì)象受裹。

① 不可變對(duì)象,以NSString為例:

NSString *originStr = @"origin";
NSString *originStrCopy = [originStr copy];//copy
NSMutableString *originStrMutableCopy = [originStr mutableCopy];//mutableCopy

內(nèi)存截圖為:
內(nèi)存截圖1

從上面的內(nèi)存截圖可以看出闻书,不可變對(duì)象copy內(nèi)存地址沒(méi)有變化名斟,而mutableCopy內(nèi)存地址發(fā)生了變化脑慧。

② 可變對(duì)象魄眉,以NSMutableString為例:

NSMutableString *mutableOriginStr = [NSMutableString stringWithString:@"mutableOrigin"];
NSMutableString *mutableOriginStrCopy = [mutableOriginStr copy];//copy
NSMutableString *mutableOriginStrMutableCopy = [mutableOriginStr mutableCopy];//mutableCopy

內(nèi)存截圖為:
內(nèi)存截圖2

從上面的內(nèi)存截圖可以看出,可變對(duì)象copy和mutableCopy內(nèi)存地址都發(fā)生了變化闷袒。

非集合類總結(jié):
對(duì)不可變對(duì)象復(fù)制:copy是指針復(fù)制(淺拷貝)坑律,mutableCopy是內(nèi)容復(fù)制(深拷貝)。
對(duì)可變對(duì)象復(fù)制:copy和mutableCopy都是內(nèi)容復(fù)制(深拷貝)囊骤,但是copy返回的是不可變對(duì)象晃择。

2. 集合類對(duì)象的copy和mutableCopy

① 不可變對(duì)象,以NSArray為例:

NSArray *originArray = @[[NSMutableString stringWithString:@"a"],@"b",@"c"];
NSArray *originArrayCopy = [originArray copy];//copy
NSMutableArray *originArrayMutableCopy = [originArray mutableCopy];//mutableCopy

內(nèi)存截圖為:
內(nèi)存截圖3

從上圖可以看出也物,不可變對(duì)象的copy內(nèi)存地址沒(méi)變宫屠,mutableCopy內(nèi)存地址發(fā)生了變化,但是不論copy還是mutableCopy滑蚯,集合內(nèi)的對(duì)象的內(nèi)存地址并沒(méi)有發(fā)生變化浪蹂,說(shuō)明copy和mutableCopy對(duì)于集合內(nèi)的對(duì)象來(lái)說(shuō)抵栈,都是只復(fù)制了指針。

添加一個(gè)元素:

[originArrayMutableCopy addObject:@"d"];

內(nèi)存截圖為:
內(nèi)存截圖4

刪除一個(gè)元素

[originArrayMutableCopy removeLastObject];

內(nèi)存截圖為:
內(nèi)存截圖5

修改一個(gè)元素:

NSMutableString *testString = [originArrayMutableCopy firstObject];
//testString = @"a changeValue";這樣寫是有問(wèn)題的坤次,會(huì)改變testString的指針古劲,其實(shí)是將@"a changeValue"臨時(shí)對(duì)象賦給了testString
[testString appendString:@" changeValue"];

內(nèi)存截圖為:
內(nèi)存截圖6

可以看到,當(dāng)一個(gè)集合里的對(duì)象改變了缰猴,其他集合里的對(duì)象也改變了产艾,說(shuō)明指針指向的是同一塊內(nèi)存地址。

② 可變對(duì)象滑绒,以NSMutableArray為例:

NSMutableArray *mutableOriginArray = [[NSMutableArray alloc] initWithArray:@[@"a",@"b",@"c"] copyItems:YES];
NSArray *mutableOriginArrayCopy = [mutableOriginArray copy];
NSMutableArray *mutableOriginArrayMutableCopy = [mutableOriginArray mutableCopy];

內(nèi)存截圖為:
內(nèi)存地址7

從上圖可以看出闷堡,可變對(duì)象的copy和mutableCopy內(nèi)存地址都發(fā)生了變化,但是不論copy還是mutableCopy疑故,集合內(nèi)的對(duì)象的內(nèi)存地址并沒(méi)有發(fā)生變化缚窿,說(shuō)明copy和mutableCopy對(duì)于集合內(nèi)的對(duì)象來(lái)說(shuō),都是只復(fù)制了指針焰扳。

集合類總結(jié)
對(duì)不可變對(duì)象復(fù)制:copy是指針復(fù)制(淺拷貝)倦零,mutableCopy是內(nèi)容復(fù)制(深拷貝)。
對(duì)可變對(duì)象復(fù)制:copy和mutableCopy都是內(nèi)容復(fù)制(深拷貝)吨悍,但是copy返回的是不可變對(duì)象扫茅。
與非集合類不同的是:集合內(nèi)的對(duì)象都是指針復(fù)制!S稀葫隙!,即所謂的集合的單層深復(fù)制(one-level-deep copy)躏仇。

集合類真正意義的深拷貝

想要實(shí)現(xiàn)真正意義上的深復(fù)制(即集合對(duì)象和集合內(nèi)的對(duì)象都進(jìn)行內(nèi)容復(fù)制)恋脚,可以用下面的方法:

NSMutableArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:mutableOriginArray]];

內(nèi)存截圖為:

內(nèi)存截圖8
內(nèi)存截圖9

從上面兩張內(nèi)存截圖可以看出,使用歸檔的方法實(shí)現(xiàn)了真正的元素對(duì)象的拷貝焰手。

參考文檔:

(1) Blog:copy 與 mutableCopy
(2) iPhone Dev:iOS開(kāi)發(fā)之深拷貝與淺拷貝(mutableCopy與Copy)詳解
(3) 《招聘一個(gè)靠譜的iOS》面試題參考答案
(4) iOS 集合的深復(fù)制與淺復(fù)制

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末糟描,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子书妻,更是在濱河造成了極大的恐慌船响,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件躲履,死亡現(xiàn)場(chǎng)離奇詭異见间,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)工猜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門米诉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人篷帅,你說(shuō)我怎么就攤上這事史侣『瓜” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵抵窒,是天一觀的道長(zhǎng)弛针。 經(jīng)常有香客問(wèn)我,道長(zhǎng)李皇,這世上最難降的妖魔是什么削茁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮掉房,結(jié)果婚禮上茧跋,老公的妹妹穿的比我還像新娘。我一直安慰自己卓囚,他們只是感情好瘾杭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著哪亿,像睡著了一般粥烁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蝇棉,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天讨阻,我揣著相機(jī)與錄音妖胀,去河邊找鬼咧纠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碘勉,可吹牛的內(nèi)容都是我干的板辽。 我是一名探鬼主播奇瘦,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼劲弦!你這毒婦竟也來(lái)了耳标?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瓶您,失蹤者是張志新(化名)和其女友劉穎麻捻,沒(méi)想到半個(gè)月后纲仍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體呀袱,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年郑叠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了夜赵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡乡革,死狀恐怖寇僧,靈堂內(nèi)的尸體忽然破棺而出摊腋,到底是詐尸還是另有隱情,我是刑警寧澤嘁傀,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布兴蒸,位于F島的核電站,受9級(jí)特大地震影響细办,放射性物質(zhì)發(fā)生泄漏橙凳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一笑撞、第九天 我趴在偏房一處隱蔽的房頂上張望岛啸。 院中可真熱鬧,春花似錦茴肥、人聲如沸坚踩。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞬铸。三九已至,卻和暖如春础锐,著一層夾襖步出監(jiān)牢的瞬間赴捞,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工郁稍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赦政,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓耀怜,卻偏偏與公主長(zhǎng)得像恢着,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子财破,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353