iOS Copy

一写妥、拷貝對(duì)象的基本概念

拷貝一個(gè)對(duì)象的副本鸳粉,開(kāi)辟一塊新的內(nèi)存來(lái)存儲(chǔ)副本對(duì)象

二捌蚊、淺拷貝和深拷貝

1集畅、淺拷貝

淺拷貝就是對(duì)對(duì)象內(nèi)存地址的拷貝,讓目標(biāo)指針和源指針指向同一片內(nèi)存空間缅糟。
淺拷貝只是對(duì)對(duì)象的簡(jiǎn)單拷貝挺智,讓幾個(gè)指針共用一片內(nèi)存,當(dāng)內(nèi)存銷(xiāo)毀的時(shí)候窗宦,指向這片內(nèi)存的幾個(gè)指針需要重新定義才可以使用赦颇,不然會(huì)成為野指針。
在iOS中赴涵,使用retain媒怯,是一種更加保險(xiǎn)的淺拷貝。它讓幾個(gè)指針共用同一塊內(nèi)存空間髓窜。 由于引用計(jì)數(shù)的存在扇苞,不會(huì)輕易的銷(xiāo)毀內(nèi)存,達(dá)到更加簡(jiǎn)單使用的目的寄纵。

2鳖敷、深拷貝

深拷貝是指拷貝對(duì)象的具體內(nèi)容,而內(nèi)存地址是自主分配的程拭,拷貝結(jié)束之后哄陶,兩個(gè)對(duì)象雖然存的值是相同的,但是內(nèi)存地址不一樣哺壶,兩個(gè)對(duì)象也互不影響屋吨,互不干涉蜒谤。

三、協(xié)議

如果一個(gè)對(duì)象想具備拷貝的功能至扰,必須實(shí)現(xiàn)協(xié)議鳍徽。
NSObject自帶的常用的對(duì)象有:NSNumber、NSString敢课、NSArray阶祭、NSDictionary、NSMutableString直秆、NSMutableArray濒募、NSMutableDictionary
iOS提供了copy和mutableCopy方法,顧名思義圾结,copy就是復(fù)制了一個(gè)imutable的對(duì)象瑰剃,而mutableCopy就是復(fù)制了一個(gè)mutable的對(duì)象。
當(dāng)然在iOS中并不是所有的對(duì)象都支持copy和mutableCopy筝野,遵守NSCopying 協(xié)議的類(lèi)可以發(fā)送copy消息晌姚,遵守NSMutableCopying 協(xié)議的類(lèi)才可以發(fā)送mutableCopy消息。假如發(fā)送了一個(gè)沒(méi)有遵守上述兩協(xié)議而發(fā)送copy或者mutableCopy歇竟,那么就會(huì)發(fā)生異常挥唠。但是默認(rèn)的iOS類(lèi)并沒(méi)有遵守這兩個(gè)協(xié)議。如果想自定義copy就必須遵守NSCopying焕议,并且實(shí)現(xiàn)copyWithZone:方法宝磨,如果想自定義mutableCopy就必須遵守NSMutableCopying,并且實(shí)現(xiàn)mutableCopyWithZone:方法盅安。

四唤锉、copy和retain的區(qū)別

copy是創(chuàng)建一個(gè)對(duì)象,retain是創(chuàng)建一個(gè)指針宽堆。
copy屬性表示兩個(gè)對(duì)象內(nèi)容相同腌紧,新的對(duì)象引用計(jì)數(shù)為1 茸习,與舊有對(duì)象的引用計(jì)數(shù)無(wú)關(guān)畜隶,舊有對(duì)象沒(méi)有變化。copy減少對(duì)象對(duì)上下文的依賴号胚。
retain屬性表示兩個(gè)對(duì)象地址相同(建立一個(gè)指針籽慢,指針拷貝),內(nèi)容當(dāng)然相同猫胁,這個(gè)對(duì)象的引用計(jì)數(shù)+1箱亿。
也就是說(shuō),retain 是指針拷貝(淺拷貝)弃秆,copy 是對(duì)象拷貝(深拷貝)届惋。

五髓帽、探究

#define MyLog(Comment, Obj) NSLog(@"注釋:%@_指針地址:%p_對(duì)象地址:%p_對(duì)象:%@_引用計(jì)數(shù):%ld", Comment, &Obj, Obj, Obj, [Obj retainCount]);

1、系統(tǒng)的非容器類(lèi)對(duì)象

(NSString脑豹,NSNumber等一類(lèi)的對(duì)象)

1.1郑藏、不可變對(duì)象

NSString *string = @"Hello";
MyLog(@"String", string);
NSString *copyString = [string copy];
MyLog(@"CopyString", copyString);
NSString *mutableCopyString = [string mutableCopy];
MyLog(@"MutableCopyString", mutableCopyString);
    
string = @"World";
MyLog(@"String", string);
MyLog(@"CopyString", copyString);
MyLog(@"MutableCopyString", mutableCopyString);
2019-12-17 14:13:05.888336+0800 CopyTest[5239:233232] 注釋:String_指針地址:0x7ffeee082a38_對(duì)象地址:0x101b7c050_對(duì)象:Hello_引用計(jì)數(shù):-1
2019-12-17 14:13:07.112412+0800 CopyTest[5239:233232] 注釋:CopyString_指針地址:0x7ffeee082a30_對(duì)象地址:0x101b7c050_對(duì)象:Hello_引用計(jì)數(shù):-1
2019-12-17 14:13:10.228491+0800 CopyTest[5239:233232] 注釋:MutableCopyString_指針地址:0x7ffeee082a28_對(duì)象地址:0x600003558990_對(duì)象:Hello_引用計(jì)數(shù):1
2019-12-17 14:13:16.821985+0800 CopyTest[5239:233232] 注釋:String_指針地址:0x7ffeee082a38_對(duì)象地址:0x101b7c0f0_對(duì)象:World_引用計(jì)數(shù):-1
2019-12-17 14:13:25.889237+0800 CopyTest[5239:233232] 注釋:CopyString_指針地址:0x7ffeee082a30_對(duì)象地址:0x101b7c050_對(duì)象:Hello_引用計(jì)數(shù):-1
2019-12-17 14:13:58.920537+0800 CopyTest[5239:233232] 注釋:MutableCopyString_指針地址:0x7ffeee082a28_對(duì)象地址:0x600003558990_對(duì)象:Hello_引用計(jì)數(shù):1

查看Log可發(fā)現(xiàn),string和copyString指向的是同一塊內(nèi)存區(qū)域瘩欺。而mutableCopyString則是我們所說(shuō)的真正意義上的拷貝必盖,系統(tǒng)為其分配了新內(nèi)存,引用計(jì)數(shù)為1俱饿,指針?biāo)赶虻淖址畠?nèi)容和string所指的一樣歌粥。

1.2、可變對(duì)象

NSMutableString *mutableString = [NSMutableString stringWithFormat:@"Hello"];
MyLog(@"MutableString", mutableString);
NSString *copyMutableString = [mutableString copy];
MyLog(@"CopyMutableString", copyMutableString);
NSString *mutableCopyMutableString = [mutableString mutableCopy];
MyLog(@"MutableCopyMutableString", mutableCopyMutableString);
    
mutableString = [NSMutableString stringWithFormat:@"World"];
MyLog(@"MutableString", mutableString);
MyLog(@"CopyMutableString", copyMutableString);
MyLog(@"MutableCopyMutableString", mutableCopyMutableString);
2019-12-17 14:22:47.659570+0800 CopyTest[5512:258797] 注釋:MutableString_指針地址:0x7ffee358ea38_對(duì)象地址:0x600002204c00_對(duì)象:Hello_引用計(jì)數(shù):1
2019-12-17 14:22:49.269361+0800 CopyTest[5512:258797] 注釋:CopyMutableString_指針地址:0x7ffee358ea30_對(duì)象地址:0x8d16218c3feb7c2b_對(duì)象:Hello_引用計(jì)數(shù):-1
2019-12-17 14:22:53.712337+0800 CopyTest[5512:258797] 注釋:MutableCopyMutableString_指針地址:0x7ffee358ea28_對(duì)象地址:0x600002254000_對(duì)象:Hello_引用計(jì)數(shù):1
2019-12-17 14:22:58.449147+0800 CopyTest[5512:258797] 注釋:MutableString_指針地址:0x7ffee358ea38_對(duì)象地址:0x600002204ab0_對(duì)象:World_引用計(jì)數(shù):1
2019-12-17 14:23:06.121620+0800 CopyTest[5512:258797] 注釋:CopyMutableString_指針地址:0x7ffee358ea30_對(duì)象地址:0x8d16218c3feb7c2b_對(duì)象:Hello_引用計(jì)數(shù):-1
2019-12-17 14:23:09.417593+0800 CopyTest[5512:258797] 注釋:MutableCopyMutableString_指針地址:0x7ffee358ea28_對(duì)象地址:0x600002254000_對(duì)象:Hello_引用計(jì)數(shù):1

copy產(chǎn)生的對(duì)象是不可變的拍埠,mutableCopy產(chǎn)生的對(duì)象是可變的
對(duì)于系統(tǒng)的非容器類(lèi)對(duì)象失驶,我們可以認(rèn)為,如果對(duì)一不可變對(duì)象拷貝械拍,copy是指針拷貝(淺拷貝)突勇,mutableCopy就是對(duì)象拷貝(深拷貝)。如果是對(duì)可變對(duì)象拷貝坷虑,都是深拷貝甲馋,但是copy返回的對(duì)象是不可變的。

2迄损、系統(tǒng)的容器類(lèi)對(duì)象

(NSArray定躏,NSDictionary等一類(lèi)的對(duì)象, 對(duì)于容器類(lèi)本身芹敌,上面討論的結(jié)論也是適用的痊远,需要探討的是拷貝后容器內(nèi)對(duì)象的變化。)

2.1氏捞、不可變對(duì)象

NSObject *object = [[NSObject alloc] init];
NSArray *array = @[object];
MyLog(@"Array", array);
NSArray *copyArray = [array copy];
MyLog(@"CopyArray", copyArray);
NSMutableArray *mutableCopyArray = [array mutableCopy];
MyLog(@"MutableCopyArray", mutableCopyArray);
    
array = @[object, object];
MyLog(@"Array", array);
MyLog(@"CopyArray", copyArray);
MyLog(@"MutableCopyArray", mutableCopyArray);
2019-12-17 14:48:05.654817+0800 CopyTest[6223:303565] 注釋:Array_指針地址:0x7ffeee88ca10_對(duì)象地址:0x600001384c60_對(duì)象:(
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):1
2019-12-17 14:48:05.655102+0800 CopyTest[6223:303565] 注釋:CopyArray_指針地址:0x7ffeee88ca08_對(duì)象地址:0x600001384c60_對(duì)象:(
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):2
2019-12-17 14:48:05.655236+0800 CopyTest[6223:303565] 注釋:MutableCopyArray_指針地址:0x7ffeee88ca00_對(duì)象地址:0x600001fc5b60_對(duì)象:(
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):1
2019-12-17 14:48:05.655349+0800 CopyTest[6223:303565] 注釋:Array_指針地址:0x7ffeee88ca10_對(duì)象地址:0x600001191dc0_對(duì)象:(
    "<NSObject: 0x600001384c50>",
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):1
2019-12-17 14:48:05.655451+0800 CopyTest[6223:303565] 注釋:CopyArray_指針地址:0x7ffeee88ca08_對(duì)象地址:0x600001384c60_對(duì)象:(
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):2
2019-12-17 14:48:05.655525+0800 CopyTest[6223:303565] 注釋:MutableCopyArray_指針地址:0x7ffeee88ca00_對(duì)象地址:0x600001fc5b60_對(duì)象:(
    "<NSObject: 0x600001384c50>"
)_引用計(jì)數(shù):1

copyArray是指針拷貝碧聪,而mutableCopyArray是對(duì)象拷貝,mutableCopyArray還可以改變內(nèi)部的元素:刪除或添加液茎。但是注意的是逞姿,容器內(nèi)的元素內(nèi)容都是指針拷貝。

2.2捆等、可變對(duì)象

NSObject *object = [[NSObject alloc] init];
NSMutableArray *mutableArray = [NSMutableArray arrayWithObject:object];
MyLog(@"MutableArray", mutableArray);
NSArray *copyMutableArray = [mutableArray copy];
MyLog(@"CopyMutableArray", copyMutableArray);
NSMutableArray *mutableCopyMutableArray = [mutableArray mutableCopy];
MyLog(@"MutableCopyMutableArray", mutableCopyMutableArray);
    
[mutableArray addObject:object];
MyLog(@"MutableArray", mutableArray);
MyLog(@"CopyMutableArray", copyMutableArray);
MyLog(@"MutableCopyArray", mutableCopyMutableArray);
2019-12-17 14:53:20.011397+0800 CopyTest[6368:322462] 注釋:MutableArray_指針地址:0x7ffeed6b5a30_對(duì)象地址:0x6000021f9f20_對(duì)象:(
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1
2019-12-17 14:53:26.402298+0800 CopyTest[6368:322462] 注釋:CopyMutableArray_指針地址:0x7ffeed6b5a28_對(duì)象地址:0x600002da7710_對(duì)象:(
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1
2019-12-17 14:53:35.683280+0800 CopyTest[6368:322462] 注釋:MutableCopyMutableArray_指針地址:0x7ffeed6b5a20_對(duì)象地址:0x6000021e61f0_對(duì)象:(
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1
2019-12-17 14:53:40.723298+0800 CopyTest[6368:322462] 注釋:MutableArray_指針地址:0x7ffeed6b5a30_對(duì)象地址:0x6000021f9f20_對(duì)象:(
    "<NSObject: 0x600002da7700>",
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1
2019-12-17 14:53:47.418461+0800 CopyTest[6368:322462] 注釋:CopyMutableArray_指針地址:0x7ffeed6b5a28_對(duì)象地址:0x600002da7710_對(duì)象:(
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1
2019-12-17 14:53:50.173948+0800 CopyTest[6368:322462] 注釋:MutableCopyArray_指針地址:0x7ffeed6b5a20_對(duì)象地址:0x6000021e61f0_對(duì)象:(
    "<NSObject: 0x600002da7700>"
)_引用計(jì)數(shù):1

由此可見(jiàn)滞造,對(duì)于容器而言,其元素對(duì)象始終是指針拷貝栋烤。如果需要元素對(duì)象也是對(duì)象拷貝谒养,就需要自己實(shí)現(xiàn)深拷貝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末明郭,一起剝皮案震驚了整個(gè)濱河市买窟,隨后出現(xiàn)的幾起案子丰泊,更是在濱河造成了極大的恐慌,老刑警劉巖始绍,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趁耗,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疆虚,警方通過(guò)查閱死者的電腦和手機(jī)苛败,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)径簿,“玉大人罢屈,你說(shuō)我怎么就攤上這事∑ぃ” “怎么了缠捌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)译蒂。 經(jīng)常有香客問(wèn)我曼月,道長(zhǎng),這世上最難降的妖魔是什么柔昼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任哑芹,我火速辦了婚禮,結(jié)果婚禮上捕透,老公的妹妹穿的比我還像新娘聪姿。我一直安慰自己,他們只是感情好乙嘀,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布末购。 她就那樣靜靜地躺著,像睡著了一般虎谢。 火紅的嫁衣襯著肌膚如雪盟榴。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天婴噩,我揣著相機(jī)與錄音擎场,去河邊找鬼。 笑死讳推,一個(gè)胖子當(dāng)著我的面吹牛顶籽,可吹牛的內(nèi)容都是我干的玩般。 我是一名探鬼主播银觅,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼坏为!你這毒婦竟也來(lái)了究驴?” 一聲冷哼從身側(cè)響起镊绪,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎洒忧,沒(méi)想到半個(gè)月后蝴韭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熙侍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年榄鉴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛉抓。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庆尘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巷送,到底是詐尸還是另有隱情驶忌,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布笑跛,位于F島的核電站付魔,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏飞蹂。R本人自食惡果不足惜几苍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陈哑。 院中可真熱鬧擦剑,春花似錦、人聲如沸芥颈。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)爬坑。三九已至纠屋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盾计,已是汗流浹背售担。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留署辉,地道東北人族铆。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像哭尝,于是被迫代替她去往敵國(guó)和親哥攘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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

  • 前言 1.深淺拷貝 2.copy 和 mutableCopy 介紹和用法耕姊。 3.為什么修飾block用copy? ...
    luonaerduo閱讀 438評(píng)論 0 0
  • 前言 1.深淺拷貝 2.copy 和 mutableCopy 介紹和用法茉兰。 3.為什么修飾block用copy? ...
    ildream閱讀 10,789評(píng)論 23 35
  • 淺拷貝與深拷貝 淺拷貝:指針拷貝,不產(chǎn)生新的對(duì)象欣簇,源對(duì)象的引用計(jì)數(shù)器+1 深拷貝:對(duì)象拷貝规脸,會(huì)產(chǎn)生新的對(duì)象,源對(duì)象...
    SkyMing一C閱讀 727評(píng)論 0 6
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒(méi)有地址/指針的概念1.2> 泛型1.3> 類(lèi)型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,096評(píng)論 1 32
  • 開(kāi)發(fā)中熊咽,數(shù)據(jù)處理是整個(gè)項(xiàng)目的重中之重燃辖,清晰的數(shù)據(jù)結(jié)構(gòu),安全高效的處理流程网棍,能大大提高開(kāi)發(fā)效率和系統(tǒng)的穩(wěn)定性黔龟。數(shù)據(jù)是...
    擇勢(shì)量投閱讀 917評(píng)論 0 5