對(duì)深拷貝和淺拷貝的一些學(xué)習(xí)心得

摘要 : 文章參考http://www.cocoachina.com/ios/20160803/17275.html

一開(kāi)始我一直以為拷貝方式只有兩種,并且對(duì)這兩種的拷貝方式也是分不清,然后就在網(wǎng)上學(xué)習(xí)了一下,寫一下自己的心得體會(huì),給大家分享一下.

首先 . OC對(duì)象的拷貝方式不是兩種而是三種.分別是

淺拷貝(shallow copy):在淺拷貝操作時(shí), 對(duì)于被復(fù)制的對(duì)象的每一層都是指針復(fù)制,并沒(méi)有對(duì)物理地址進(jìn)行復(fù)制,所以并不會(huì)重新開(kāi)辟新的空間.

深復(fù)制(one-level-deep copy):在深復(fù)制操作的時(shí)候,是把對(duì)象的給復(fù)制過(guò)來(lái),至少有一層是深復(fù)制.其實(shí)也不全是深復(fù)制,如果數(shù)據(jù)有很多層次,它就只復(fù)制了第一層,而第二層還是淺復(fù)制.

完全復(fù)制(real - deep copy):完全復(fù)制操作的時(shí)候,就是對(duì)于對(duì)象的每一層都進(jìn)行了復(fù)制,不僅物理地址復(fù)制,對(duì)象也復(fù)制.這才是真正的深拷貝.

圖片來(lái)源http://www.cocoachina.com/ios/20160803/17275.html

從圖片可以看出 ,我發(fā)現(xiàn)可變的對(duì)象 雖然只是用了copy ,但發(fā)現(xiàn)它并不是淺拷貝,而是深拷貝.但參數(shù)的類型竟然發(fā)生了改變,具體原因我也不清楚 ,如有大神 知道,可以幫小弟講解一下.


理解深復(fù)制(mutableCopy)

說(shuō)多無(wú)益,代碼才是王道.

NSMutableArray *array = [NSMutableArray arrayWithObjects:

[NSMutableString stringWithString:@"a"],

[NSMutableString stringWithString:@"b"],

[NSMutableString stringWithString:@"c"],

[NSMutableString stringWithString:@"d"],

nil];

NSMutableArray *array1 = [NSMutableArray arrayWithObjects:

[NSMutableString stringWithString:@"A"],

[NSMutableString stringWithString:@"B"],

[NSMutableString stringWithString:@"C"],

[NSMutableString stringWithString:@"D"],

array, nil];

NSMutableArray *array2 ;

NSMutableString *str;

array2 = [array1 mutableCopy];

str = array1[4][1];

[str appendString:@"-----1"];

NSLog(@"array2------%@",array2);

NSLog(@"array1------%@",array1);

打印出來(lái)的結(jié)果卻讓人想不明白

2016-08-26 12:08:38.277 深淺拷貝[1117:64610] array2------(

A,

B,

C,

D,

(

a,

"b-----1",

c,

d

)

)

2016-08-26 12:08:38.278 深淺拷貝[1117:64610] array1------(

A,

B,

C,

D,

(

a,

"b-----1",

c,

d

)

)


試了一下又開(kāi)了一下原文講的才知道,原來(lái)這就是深復(fù)制和完全復(fù)制的區(qū)別.

對(duì)于深復(fù)制,我一直認(rèn)為,深復(fù)制就是對(duì)于原有對(duì)象的內(nèi)容直接克隆過(guò)去,但代碼顯示的結(jié)果卻讓我產(chǎn)生疑惑,很是不明白,原來(lái)它只是復(fù)制一層對(duì)象,而不會(huì)復(fù)制第二層甚至更深層次的對(duì)象,其實(shí)對(duì)于這句話我是有疑問(wèn)的,既然是復(fù)制了第一層,那么這第一層是說(shuō)的A,B,C,D呢還是就是原本array1的層次,就是一個(gè)空的對(duì)象,但看代碼執(zhí)行的結(jié)果,我的想法應(yīng)該是對(duì)的,這個(gè)層次,對(duì)于我來(lái)說(shuō),好像并不是很清楚,同樣如果有大神知道,可以講解一下.

代碼array2 = [array1 mutableCopy]; 只是對(duì)數(shù)組array1 本身進(jìn)行內(nèi)容的拷貝.但里面的字符串對(duì)象沒(méi)有進(jìn)行內(nèi)容的拷貝,而是進(jìn)行的淺復(fù)制,只是指針的復(fù)制,對(duì)象還是公用的所以改變一個(gè)也會(huì)改變所有.

看來(lái)解決這個(gè)問(wèn)題只能再看原文章了

換了復(fù)制方式的代碼 結(jié)果還是可人的.

array2 = [[NSMutableArray alloc]initWithArray:array1 copyItems:YES];

顯示結(jié)果是

2016-08-26 12:23:25.787 深淺拷貝[1195:69165] array2------(

A,

B,

C,

D,

(

a,

b,

c,

d

)

)

2016-08-26 12:23:25.787 深淺拷貝[1195:69165] array1------(

"A-----1",

B,

C,

D,

(

a,

b,

c,

d

)

)


發(fā)現(xiàn)沒(méi)有問(wèn)題 但我總感覺(jué) 還是有問(wèn)題,

str = array1[4][1];

方法一變發(fā)現(xiàn)打印的結(jié)果又和上面的一樣

2016-08-26 12:24:42.143 深淺拷貝[1218:70070] array2------(

A,

B,

C,

D,

(

a,

"b-----1",

c,

d

)

)

2016-08-26 12:24:42.144 深淺拷貝[1218:70070] array1------(

A,

B,

C,

D,

(

a,

"b-----1",

c,

d

)

)


唉, 還是失敗了,array2 = [[NSMutableArray alloc]initWithArray:array1 copyItems:YES];僅僅只是復(fù)制了一層,而下面的一層卻沒(méi)有復(fù)制.

看來(lái)我的試一下完全復(fù)制這個(gè)方法了.原來(lái)完全復(fù)制是歸檔和解檔啊.

array2 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array1]];

輸出的結(jié)果是

2016-08-26 12:30:12.292 深淺拷貝[1265:72371] array2------(

A,

B,

C,

D,

(

a,

b,

c,

d

)

)

2016-08-26 12:30:12.293 深淺拷貝[1265:72371] array1------(

A,

B,

C,

D,

(

a,

"b-----1",

c,

d

)

)

大功告成!!!!!

類的復(fù)制 就不在自己寫了 感覺(jué)并不是很難,就直接用原作者的.

類復(fù)制說(shuō)完了對(duì)象的復(fù)制辽慕,我們來(lái)看看如何實(shí)現(xiàn)類的復(fù)制竖哩,因?yàn)楸容^簡(jiǎn)單摹芙,直接放上代碼定義類復(fù)制123456789101112131415#import@interface Person : NSObject@property(strong,nonatomic)NSString *age;

@property(strong,nonatomic)NSString *name;

@end

#import "Person.h"

@implementation Person

- (id)copyWithZone:(NSZone *)zone

{

Person *person = [[Person allocWithZone:zone] init];

person.age = self.age;

person.name = self.name;

return person;

}

@end

調(diào)用

Person *person = [[Person alloc]init];

person.age = @"dsdsd";

person.name = @"dsdsdddww";

Person *copyPerson = [person copy];?

NSLog(@"%@-----%@",copyPerson.age, copyPerson.name);可以看到copyPerson的兩個(gè)屬性和persona一樣脊另。

@property中的copy關(guān)鍵字

在設(shè)置NSString類型的屬性的時(shí)候,我們最好設(shè)置為copy類型敬惦,這樣別人使用我們定義的屬性的時(shí)候饥伊,他不管怎么改動(dòng)該屬性的賦值紊浩,都不會(huì)影響我們給該屬性賦的值,為什么呢酌呆?

下面我們來(lái)看看

如上圖所示衡载,string2的屬性是copy類型,可以看到是無(wú)法被修改的隙袁。

因?yàn)榇藭r(shí)string2和copystring的內(nèi)存地址不一樣痰娱,修改一個(gè),不會(huì)影響另外一個(gè)菩收。

上圖所示梨睁,如果string2的屬性是strong類型,就可以被修改坛梁,如下圖所示:因?yàn)榇藭r(shí)string2和copystring的內(nèi)存地址都是一樣的而姐,修改一個(gè),兩個(gè)就同時(shí)被修改copy關(guān)鍵字的NSMutableString崩潰


原因:copy關(guān)鍵字的string的setter方法實(shí)際上是把參數(shù)copy之后再賦值給變量_string划咐,那么此時(shí)變量_string雖然被申明為NSMutableString拴念,但是copy之后,就把變量_string變成了不可變的NSString類型褐缠,所以就會(huì)出現(xiàn)方法報(bào)錯(cuò)政鼠,提示對(duì)不可變的NSString使用了NSMutableString的方法appendString。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末队魏,一起剝皮案震驚了整個(gè)濱河市公般,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胡桨,老刑警劉巖官帘,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異昧谊,居然都是意外死亡刽虹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門呢诬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)涌哲,“玉大人胖缤,你說(shuō)我怎么就攤上這事》Щ” “怎么了哪廓?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)初烘。 經(jīng)常有香客問(wèn)我涡真,道長(zhǎng),這世上最難降的妖魔是什么账月? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任综膀,我火速辦了婚禮,結(jié)果婚禮上局齿,老公的妹妹穿的比我還像新娘剧劝。我一直安慰自己,他們只是感情好抓歼,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布讥此。 她就那樣靜靜地躺著,像睡著了一般谣妻。 火紅的嫁衣襯著肌膚如雪萄喳。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,268評(píng)論 1 309
  • 那天蹋半,我揣著相機(jī)與錄音他巨,去河邊找鬼。 笑死减江,一個(gè)胖子當(dāng)著我的面吹牛染突,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辈灼,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼份企,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了巡莹?” 一聲冷哼從身側(cè)響起司志,我...
    開(kāi)封第一講書(shū)人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎降宅,沒(méi)想到半個(gè)月后骂远,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腰根,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年激才,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贸营,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出岩睁,到底是詐尸還是另有隱情钞脂,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布捕儒,位于F島的核電站冰啃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏刘莹。R本人自食惡果不足惜阎毅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望点弯。 院中可真熱鬧扇调,春花似錦、人聲如沸抢肛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捡絮。三九已至熬芜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間福稳,已是汗流浹背涎拉。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留的圆,地道東北人鼓拧。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像略板,于是被迫代替她去往敵國(guó)和親毁枯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容