iOS開發(fā)中copy和mutableCopy賦值方法的異同

本文邏輯圖

本文邏輯圖

copy和mutableCopy賦值的異同
1.copy贮匕,mutableCopy都是深拷貝姐仅,也就是會重新開辟出一塊內(nèi)存來保存和原有值相同的值,原有值的變化不會修改被賦值對象的值刻盐。
2.copy的被賦值對象不可被修改掏膏,mutableCopy得到的對象可被修改。且不受原值和接受值的類型影響敦锌。
3.容器對象(數(shù)組)中的元素是淺拷貝馒疹,修改后依舊會對被賦值對象造成影響。
下面我們依次通過非容器變量和容器變量來驗證上面三條乙墙。

1.copy颖变,mutableCopy都是深拷貝,也就是會重新開辟出一塊內(nèi)存來保存和原有值相同的值听想,原有值的變化不會修改被賦值對象的值

初始化一個mStrOrigin腥刹,通過copy方法賦值給mStrFromCopy,mStrFromMCopy,輸出三者的值和地址哗魂。觀察他們的值和地址是否相同肛走,從而判斷是copy和mutableCopy是否深拷貝。

NSMutableString *mStrOrigin = [[NSMutableString alloc] initWithString:@"mStr"];
NSMutableString *mStrFromCopy = [mStrOrigin copy];
NSMutableString *mStrFromMCopy = [mStrOrigin mutableCopy];
NSLog(@"值:mStrOrigin:%@ mStrFromCopy:%@  mStrFromMCopy:%@ \n  地址:mStrOrigin:%p mStrFromCopy:%p  mStrFromMCopy:%p \n",mStrOrigin,mStrFromCopy,mStrFromMCopy,mStrOrigin,mStrFromCopy,mStrFromMCopy);

有輸出

值:mStrOrigin:mStr mStrFromCopy:mStr  mStrFromMCopy:mStr
地址:mStrOrigin:0x7fec40c5bd00 mStrFromCopy:0xa0000007274536d4  mStrFromMCopy:0x7fec40c59c00

現(xiàn)象:mStrOrigin录别,mStrFromCopy朽色,mStrFromMCopy三者地址都不一樣
結(jié)論:copy和mutableCopy是深拷貝

我們修改原值mStrOrigin 觀察mStrFromCopy,mStrFromMCopy是否會隨之變化

[mStrOrigin appendString:@"-change1"];
NSLog(@"值:mStrOrigin:%@ mStrFromCopy:%@  mStrFromMCopy:%@ \n  地址:mStrOrigin:%p mStrFromCopy:%p  mStrFromMCopy:%p \n",mStrOrigin,mStrFromCopy,mStrFromMCopy,mStrOrigin,mStrFromCopy,mStrFromMCopy);

有輸出

值:mStrOrigin:mStr-change1 mStrFromCopy:mStr  mStrFromMCopy:mStr
地址:mStrOrigin:0x7fec40c5bd00 mStrFromCopy:0xa0000007274536d4  mStrFromMCopy:0x7fec40c59c00

現(xiàn)象:隨著mStrOrigin變化,mStrFromMCopy和mStrFromMCopy均沒有隨之變化
結(jié)論:copy和mutableCopy出來的是新的內(nèi)存组题,原值改變新的值不改變葫男。
他們的賦值結(jié)構(gòu)圖如下:

copy,mutableCopy賦值示意圖1

2.copy的被賦值對象不可被修改崔列,mutableCopy得到的對象可被修改梢褐。且不受原值和接受值的類型影響旺遮。

嘗試修改mStrFromCopy(由copy方法得到),查看是否會崩潰盈咳,從而判斷copy出來的對象不可被修改的

NSMutableArray   *mArrOrigin = [[NSMutableArray alloc] init];
NSMutableString  *mstr1 = [[NSMutableString alloc] initWithString:@"value1"];
NSMutableString  *mstr2 = [[NSMutableString alloc] initWithString:@"value2"];
NSMutableString *mStrOrigin = [[NSMutableString alloc] initWithString:@"mStr"];
[mArrOrigin addObject:mstr1];
[mArrOrigin addObject:mstr2];
NSMutableArray *mArrFromCopy = [mArrOrigin copy];
NSMutableString *mStrFromCopy = [mStrOrigin copy];

[mStrFromCopy appendString:@"-change3"]; //崩潰 'Attempt to mutate immutable object with appendString:'
[mArrFromMCopy addObject:mstr3];

現(xiàn)象:數(shù)組和字符串操作均發(fā)生崩潰
結(jié)論:copy出來的內(nèi)存是不可被修改的耿眉,就算你使用可變變量指針去接受,也不能被修改

嘗試修改mStrFromMCopy和mArrFromCopy(由mutablecopy得到)鱼响,查看是否會奔潰

NSMutableString *mStrFromMCopy = [mStrOrigin mutableCopy];
NSMutableArray *mArrFromMCopy = [mArrOrigin mutableCopy];
[mStrFromMCopy appendString:@"-change4"];
[mArrFromMCopy addObject:mstr3];
NSLog(@"%@ %@",mStrFromMCopy,mArrFromMCopy);

現(xiàn)象:修改成功
結(jié)論:mutableCopy出來的數(shù)據(jù)地址可被修改

既然可以修改鸣剪,如果我們用不可變量指針接受mutableCopy值,那內(nèi)存地址還能修改嗎丈积?
我們試驗下筐骇,此處用可變變量mStrFromMCopy2弱引用指向mutableCopy的數(shù)據(jù)地址江滨,嘗試修改mStrFromMCopy2并輸出三者 查看是否能修改成功。

NSString *strFromMCopy = [mStrOrigin mutableCopy];
NSMutableString *mStrFromMCopy2 = strFromMCopy;
//輸出地址告唆,證明此時mStrFromMCopy2和strFromMCopy指向同一個數(shù)據(jù)內(nèi)存地址
NSLog(@"值:strFromMCopy:%@  mStrFromMCopy2:%@ 地址:strFromMCopy:%p mStrFromMCopy2:%p",strFromMCopy,mStrFromMCopy2,strFromMCopy,mStrFromMCopy2);
[mStrFromMCopy2 appendString:@"-change5"];
NSLog(@"值:strFromMCopy:%@  mStrFromMCopy2:%@ 地址:strFromMCopy:%p mStrFromMCopy2:%p",strFromMCopy,mStrFromMCopy2,strFromMCopy,mStrFromMCopy2);

現(xiàn)象:修改mStrFromMCopy2成功
結(jié)論:mutableCopy出來的數(shù)據(jù)地址可被修改间雀,就算接受指針是不可變類型。此處還說明一個問題茄螃,即指針可以指向不同類型的數(shù)據(jù)內(nèi)存

剛才試驗發(fā)現(xiàn)【原值是可變對象连锯,用不可變類型的指針去獲取mutableCopy得到的值,發(fā)現(xiàn)數(shù)據(jù)地址可被修改】
那如果原值本身就不可修改拼弃,那mutableCopy后的被賦值對象是否也可修改摇展。

//創(chuàng)建不可變對象
NSString *strOrigin = [[NSString alloc] initWithUTF8String:"string 1"];
mStrFromMCopy = [strOrigin mutableCopy];
[mStrFromMCopy appendString:@"-change6"];
NSLog(@"值:strOrigin %@,mStrFromMCopy %@",strOrigin,mStrFromMCopy);

輸出

值:strOrigin string 1盯孙,mStrFromMCopy string 1-change6

現(xiàn)象:修改mStrFromMCopy成功
結(jié)論:mutableCopy出來的數(shù)據(jù)地址可被修改振惰,就算原值是不可變類型

3.容器變量中元素均是淺拷貝

創(chuàng)建一個可變?nèi)萜鱩ArrOrigin垄懂,初始化添加value1痛垛,value2兩個元素匙头。并通過copy和mutableCopy賦值給mArrFromCopy乾胶,mArrFromMCopy朽寞。為原值增加一個元素value3脑融,輸出三者地址和值缩宜。查看地址和值觀察是否是深拷貝

NSMutableArray   *mArrOrigin = [[NSMutableArray alloc] init];
NSMutableString  *mstr1 = [[NSMutableString alloc] initWithString:@"value1"];
NSMutableString  *mstr2 = [[NSMutableString alloc] initWithString:@"value2"];
NSMutableString  *mstr3 = [[NSMutableString alloc] initWithString:@"value3"];
[mArrOrigin addObject:mstr1];
[mArrOrigin addObject:mstr2];
NSMutableArray *mArrFromCopy = [mArrOrigin copy];
NSMutableArray *mArrFromMCopy = [mArrOrigin mutableCopy];
[mArrOrigin addObject:mstr3];
NSLog(@"值:mArrOrigin :%@ mArrFromCopy:%@ mArrFromMCopy%@\n  地址:mArrOrigin :%p\n mArrFromCopy:%p\n mArrFromMCopy:%p\n",mArrOrigin,mArrFromCopy,mArrFromMCopy,mArrOrigin,mArrFromCopy,mArrFromMCopy);

輸出:

值:
mArrOrigin :(
    value1,
    value2,
    value3
) mArrFromCopy:(
    value1,
    value2
) mArrFromMCopy(
    value1,
    value2
)
地址:
mArrOrigin :0x7fe102d0e380 
mArrFromCopy:0x7fe102d26070
mArrFromMCopy:0x7fe102d26090

現(xiàn)象:mArrFromCopy锻煌,mArrFromMCopy出來的容器本身是新的地址宋梧。(不可變?nèi)萜魍?br> 結(jié)論:copy和mutableCopy出來的是新的地址,原容器改變释涛,新容器不改變倦沧。賦值結(jié)構(gòu)圖如下

容器賦值結(jié)構(gòu)示意圖2

容器本身不變展融,那么里面的元素呢?
我們修改原來容器中元素的值mstr1扑浸,輸出三個容器暂雹,觀察他們的值是否會改變,從而來判斷容器對象的copy和mutableCopy賦值是否元素也會深拷貝

[mstr1 appendString:@"-change2"];
NSLog(@"值:mArrOrigin :%@ mArrFromCopy:%@ mArrFromMCopy%@\n  地址:mArrOrigin :%p\n mArrFromCopy:%p\n mArrFromMCopy:%p\n",mArrOrigin,mArrFromCopy,mArrFromMCopy,mArrOrigin,mArrFromCopy,mArrFromMCopy);

輸出

值:
mArrOrigin :(
    "value1-change2",
    value2,
    value3
) mArrFromCopy:(
    "value1-change2",
    value2
) mArrFromMCopy(
    "value1-change2",
    value2
) 
地址:
mArrOrigin :0x7fe102d0e380
mArrFromCopy:0x7fe102d26070
mArrFromMCopy:0x7fe102d26090

現(xiàn)象:mArrFromCopy仙逻,mArrFromMCopy的元素隨之改變
結(jié)論:容器的copy和mutableCopy賦值中,容器本身是深拷貝檬贰,容器中的元素依舊是淺拷貝
結(jié)構(gòu)示意圖如下:


容器賦值結(jié)構(gòu)示意圖3

綜上所述:
1.copy和mutableCopy都是深拷貝
2.copy和mutableCopy生成的內(nèi)存地址上的數(shù)據(jù)是否可變跟原值類型和被賦值的指針類型無關(guān)翁涤。
如不可變數(shù)據(jù)copy出來的內(nèi)存萌踱,用可變指針指向,當(dāng)你嘗試修改的時候鸳粉,仍然會發(fā)生崩潰届谈。提示不可修改

3.容器對象本身遵循上面規(guī)則弯汰,容器中的元素依舊是淺拷貝(即多個指針指向一個數(shù)據(jù)地址)

項目地址https://github.com/ai966669/lbCopyAndMutableCopy

交流qq:578172874

錯誤之處希望能幫忙提出來,一起學(xué)習(xí),O(∩_∩)O謝謝了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曙搬,一起剝皮案震驚了整個濱河市织鲸,隨后出現(xiàn)的幾起案子溪胶,更是在濱河造成了極大的恐慌,老刑警劉巖瀑踢,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件橱夭,死亡現(xiàn)場離奇詭異桑逝,居然都是意外死亡,警方通過查閱死者的電腦和手機茬暇,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勒奇,“玉大人巧骚,你說我怎么就攤上這事】⒈模” “怎么了沧奴?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵扼仲,是天一觀的道長屠凶。 經(jīng)常有香客問我肆资,道長,這世上最難降的妖魔是什么唉韭? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任属愤,我火速辦了婚禮酸役,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘贱呐。我一直安慰自己入桂,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布馁蒂。 她就那樣靜靜地躺著,像睡著了一般劣纲。 火紅的嫁衣襯著肌膚如雪谁鳍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天绷柒,我揣著相機與錄音涮因,去河邊找鬼。 笑死嗜湃,一個胖子當(dāng)著我的面吹牛澜掩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刚陡,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼筐乳,長吁一口氣:“原來是場噩夢啊……” “哼乔妈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起贮懈,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤朵你,失蹤者是張志新(化名)和其女友劉穎揣非,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體忌傻,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年镰矿,在試婚紗的時候發(fā)現(xiàn)自己被綠了秤标。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宙刘。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡悬包,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出布近,到底是詐尸還是另有隱情,我是刑警寧澤棵譬,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站琅束,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏料滥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一葵腹、第九天 我趴在偏房一處隱蔽的房頂上張望屿岂。 院中可真熱鬧,春花似錦爷怀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柒室。三九已至,卻和暖如春空骚,著一層夾襖步出監(jiān)牢的瞬間不脯,已是汗流浹背府怯。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工牺丙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冲簿,地道東北人亿昏。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像吝沫,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惨险,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,573評論 2 353

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