iOS 深拷貝與淺拷貝

本文參考

博文配圖
容器類和非容器類
  1. 容器類:數(shù)組侈百、字典完沪、集合等。

    • 容器類不可變對(duì)象: 比如NSArray
    • 容器類可變對(duì)象: 比如NSMutableArray
  2. 非容器類:字符串

    • 非容器類不可變對(duì)象,比如NSString
    • 非容器類可變對(duì)象:比如NSMutableString

初步解釋
  1. 非容器類。

    • 淺拷貝:拷貝地址(對(duì)非容器類的淺拷貝就是拷貝對(duì)象的地址戏挡,對(duì)象里面存的內(nèi)容仍然是一份,沒有新的內(nèi)存被分配晨仑。)
    • 深拷貝:拷貝內(nèi)容(對(duì)非容器類的深拷貝就是重新分配一塊內(nèi)存褐墅,然后把另一個(gè)對(duì)象的內(nèi)容原封不動(dòng)的給我拿過來。)
  2. 容器類

    • 淺拷貝:生成一個(gè)新的容器(也就是“殼”)洪己,但是里面保存的元素的指針還是指向原來的元素地址妥凳。也就是說,對(duì)于容器類的淺拷貝來說答捕,容器的地址是不同的逝钥,但是里面的內(nèi)容地址是相同的,修改其中一個(gè)的內(nèi)容拱镐,會(huì)使另一個(gè)的也跟著變化艘款。(容器類的淺拷貝是對(duì)容器里的內(nèi)容不進(jìn)行拷貝齐莲,兩個(gè)容器的地址是不同的,但容器里的所裝的東西是一樣的磷箕,在一個(gè)容器中修改值,則另一個(gè)淺拷貝的容器中的值也會(huì)變化阵难。)
    • 深拷貝:不光生成一個(gè)新的容器岳枷,對(duì)容器里面的元素也進(jìn)行拷貝。
image

immutableObject呜叫、mutableObject

immutableObject空繁,不可變對(duì)象如:NSString,NSArray等
mutableObject朱庆,可變對(duì)象例如:NSMutableString,NSMutableArray等


copy 和 mutablecopy

****copy 和 mutablecopy主要是為了生成對(duì)象的副本來使用****盛泡。

  • copy:copy出來的對(duì)象類型總是不可變的(例如, NSString, NSDictionary, NSArray等等)。

  • mutablecopy:mutableCopy拷貝出來的對(duì)象類型總是可變類型(例如, NSMutableString, NSMutableDictionary, NSMutableArray等等)

注意:產(chǎn)生一個(gè)對(duì)象的可變副本并不要求被復(fù)制的對(duì)象是可變的娱颊,同理傲诵,可變對(duì)象也可以創(chuàng)建一個(gè)不可變副本。也就是說箱硕,mutableCooy和copy對(duì)于不可變對(duì)象和可變對(duì)象都可以使用拴竹。

1.對(duì)于非容器類(非集合類)對(duì)象
  • 對(duì)于不可變對(duì)象(immutableObject)

    • copy,淺拷貝(指針拷貝)剧罩。返回的是一個(gè)不可變類型的對(duì)象栓拜。(只有這一個(gè)是淺拷貝,不可變對(duì)象的copy)
    • mutableCopy惠昔,深拷貝(內(nèi)容拷貝)幕与。返回的是一個(gè)可變類型的對(duì)象。
  • 對(duì)于可變對(duì)象(mutableObject)

    • copy镇防,深拷貝(內(nèi)容拷貝)啦鸣。返回的是一個(gè)不可變類型的對(duì)象。
    • mutableCopy来氧,深拷貝(內(nèi)容拷貝)赏陵。返回的是一個(gè)可變類型的對(duì)象。
[immutableObject copy]          //淺拷貝
[immutableObject mutableCopy]   //深拷貝
[mutableObject copy]            //深拷貝
[mutableObject mutableCopy]     //深拷貝
2.對(duì)于容器類(集合類)對(duì)象
  • 對(duì)于不可變對(duì)象(immutableObject)

    • copy饲漾,淺拷貝(指針拷貝)蝙搔。返回的是一個(gè)不可變類型的對(duì)象。(只有這一個(gè)是淺拷貝考传,不可變對(duì)象的copy)
    • mutableCopy吃型,深拷貝(內(nèi)容拷貝)。返回的是一個(gè)可變類型的對(duì)象僚楞。
  • 對(duì)于可變對(duì)象(mutableObject)

    • copy勤晚,深拷貝(內(nèi)容拷貝)枉层。返回的是一個(gè)不可變類型的對(duì)象。
    • mutableCopy赐写,深拷貝(內(nèi)容拷貝)鸟蜡。返回的是一個(gè)可變類型的對(duì)象。

用代碼簡單表示如下:(注意挺邀,容器類的淺拷貝是容器新生成揉忘,里面的元素還是指向原來的)

[immutableObject copy]          //淺拷貝
[immutableObject mutableCopy]   //深拷貝
[mutableObject copy]            //深拷貝
[mutableObject mutableCopy]     //深拷貝
strong和copy的代碼測(cè)試
  • copy只能修飾不可變類型,當(dāng)修飾可變類型時(shí)端铛,編譯雖然不會(huì)出錯(cuò)泣矛,但是copy出來的是一個(gè)不可變類型對(duì)象,它被賦值給一個(gè)可變類型對(duì)象禾蚕,當(dāng)調(diào)用其方法修改其內(nèi)容時(shí)會(huì)崩潰您朽。
  • 注意:*NSString,對(duì)不可變類型的指針重新賦值换淆,會(huì)改變其地址哗总。NSString str = @"xxxxxx";//地址為0x100001050;str = @"ssssss";//地址為0x1000010d0
  • 所以說倍试,如果用strong修飾NSString魂奥,賦值的來源是不可變(NSString)的話,即使賦值來源的內(nèi)容被更改了易猫,也不會(huì)影響被賦值的NSString對(duì)象耻煤;copy也是如此,雖然對(duì)于賦值來源是不可變(NSString)的拷貝是淺拷貝准颓,但即使賦值來源的內(nèi)容改變了哈蝇,也不會(huì)有影響。因?yàn)橘x值來源會(huì)重新指向一個(gè)地址攘已,不是在原地址上更改內(nèi)容炮赦。
@interface Kaobei : NSObject
@property (strong,nonatomic) NSString *strStrong;
@property (copy,nonatomic) NSString *strCopy;
@end
@implementation Kaobei

- (void)test{
    
    NSString *str = @"xxxxxx";
    
    self.strStrong = str;
    
    self.strCopy = str;
    
    NSLog(@"str = %p",str);             //str = 0x100001050
    NSLog(@"strStrong = %p",_strStrong);//strStrong = 0x100001050
    NSLog(@"strCopy = %p",_strCopy);    //strCopy = 0x100001050
    
    str = @"ssssss";
    
    NSLog(@"str = %p",str);             //str = 0x1000010d0
    NSLog(@"strStrong = %p",_strStrong);//strStrong = 0x100001050
    NSLog(@"strCopy = %p",_strCopy);    //strCopy = 0x100001050

}

@end

使用copy而不用strong的原因

因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用 copy 的目的是為了讓本對(duì)象的屬性不受外界影響,使用 copy 無論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.
如果我們使用是 strong ,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.

關(guān)于retain和copy、mutableCopy的異同點(diǎn)
  1. retain:始終是淺拷貝样勃。引用計(jì)數(shù)每次加一吠勘。返回對(duì)象是否可變與被復(fù)制的對(duì)象保持一致。

  2. copy:對(duì)于可變對(duì)象為深拷貝峡眶,引用計(jì)數(shù)不改變剧防;對(duì)于不可變對(duì)象是淺拷貝,引用計(jì)數(shù)每次加一辫樱。始終返回一個(gè)不可變對(duì)象峭拘。

  3. mutableCopy:始終是深拷貝,引用計(jì)數(shù)不改變。始終返回一個(gè)可變對(duì)象鸡挠。

自定義類對(duì)象之間的深淺拷貝問題

在Objective-C中并不是所有的類都支持拷貝辉饱;只有遵循NSCopying協(xié)議的類,才支持copy拷貝拣展,只有遵循NSMutableCopying協(xié)議的類彭沼,才支持mutableCopy拷貝。如果沒有遵循拷貝協(xié)議备埃,拷貝時(shí)會(huì)出錯(cuò)姓惑。

如果我們想再我們自定義的類中支持copy和mutableCopy那么我們就需要使我們定義的類遵循NSCopying和NSMutableCopying協(xié)議,代碼如下:

@interface Test : NSObject <NSCopying, NSMutableCopying>

然后再重寫-(id) copyWithZone : (NSZone *) zone 和 -(id)mutableCopyWithZone : (NSZone *) zone

重寫-(id) copyWithZone :(NSZone *)zone方法如下

//淺拷貝
-(id) copyWithZone : (NSZone *) zone
{
    return [self retain];     
}
 
 
//深拷貝
-(id) mutableCopyWithZone : (NSZone *) zone
{
    Test *test = [[Test allocWithZone : zone] init];
    test.property = self.property;
    return test;   
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瓜喇,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子歉糜,更是在濱河造成了極大的恐慌乘寒,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匪补,死亡現(xiàn)場(chǎng)離奇詭異伞辛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)夯缺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蚤氏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人踊兜,你說我怎么就攤上這事竿滨。” “怎么了捏境?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵于游,是天一觀的道長。 經(jīng)常有香客問我垫言,道長贰剥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任筷频,我火速辦了婚禮蚌成,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘凛捏。我一直安慰自己担忧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布坯癣。 她就那樣靜靜地躺著涵妥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蓬网,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天窒所,我揣著相機(jī)與錄音,去河邊找鬼帆锋。 笑死吵取,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锯厢。 我是一名探鬼主播皮官,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼实辑!你這毒婦竟也來了捺氢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤剪撬,失蹤者是張志新(化名)和其女友劉穎摄乒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體残黑,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡馍佑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了梨水。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拭荤。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖疫诽,靈堂內(nèi)的尸體忽然破棺而出舅世,到底是詐尸還是另有隱情,我是刑警寧澤奇徒,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布歇终,位于F島的核電站,受9級(jí)特大地震影響逼龟,放射性物質(zhì)發(fā)生泄漏评凝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一腺律、第九天 我趴在偏房一處隱蔽的房頂上張望奕短。 院中可真熱鬧,春花似錦匀钧、人聲如沸翎碑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽日杈。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間莉擒,已是汗流浹背酿炸。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涨冀,地道東北人填硕。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像鹿鳖,于是被迫代替她去往敵國和親扁眯。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

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

  • 1翅帜、對(duì)象拷貝有兩種方式:淺復(fù)制和深復(fù)制姻檀。顧名思義,淺復(fù)制涝滴,并不拷貝對(duì)象本身绣版,僅僅是拷貝指向?qū)ο蟮闹羔槪簧顝?fù)制是直接...
    滴答大閱讀 775評(píng)論 0 2
  • 1狭莱、淺拷貝: 拷貝了指向?qū)ο蟮闹羔?并沒有復(fù)制對(duì)象本身,兩個(gè)指針指向同一片地址空間. 2僵娃、深拷貝:重新復(fù)制了一個(gè)新...
    一滴礦泉水閱讀 473評(píng)論 0 1
  • 首先提出一個(gè)問題 @property聲明的NSString(或NSArray概作,NSDictionary)腋妙,為什么經(jīng)...
    hanzhansen閱讀 452評(píng)論 0 4
  • 深拷貝和淺拷貝蘋果官網(wǎng)上的解釋如下: There are two kinds of object copying:...
    FlyElephant閱讀 629評(píng)論 1 4
  • 大家好,我是西瓜讯榕,現(xiàn)居廣州骤素。在今年想要回顧梳理一下OC的相關(guān)知識(shí)點(diǎn)。今天就先從基礎(chǔ)但不簡單的深拷貝與淺拷貝開始吧愚屁。...
    watermelon_lp閱讀 416評(píng)論 0 5