iOS內(nèi)存管理系列2之 copy和strong修飾數(shù)組及字符串對(duì)象的本質(zhì)區(qū)別探究

我覺得我這個(gè)人什么都好字管,就是有時(shí)候有點(diǎn)懶 啰挪,搞了三年多iOS開發(fā)了,回頭一看網(wǎng)上都沒有留下自己的痕跡嘲叔,昨天跟一位CTO聊天亡呵,講到職業(yè)發(fā)展的道路,他跟我說借跪,作為一個(gè)技術(shù)人員政己,要懂得分享,要學(xué)會(huì)傳播自己的知識(shí),而不能掖著藏著歇由,你在分享的過程中卵牍,不僅自己對(duì)知識(shí)的理解更到位,還能擴(kuò)大自己在圈子里的影響力沦泌,走上更好的職業(yè)發(fā)展之路糊昙,聽完他的話,我覺得我浪費(fèi)了幾年美好的光陰谢谦,所以我決定慢慢的把自己懂得東西分享出來释牺,跟大家一起交流一起進(jìn)步,如果有講的不好的地方回挽,希望大家多多斧正没咙。
下面進(jìn)入今天的主題,一直以來不斷的有人問我關(guān)于內(nèi)存管理方面的內(nèi)容千劈,我也回答了很多祭刚,今天我就將內(nèi)存管理方面的一些重要的東西拆成小的模塊逐一的講解下,今天要講的是字符串里面為什么要用copy來修飾墙牌。 請(qǐng)看下面的代碼截圖:我定義了四個(gè)屬性涡驮,分別用strong來修飾的NSString和用copy來修飾的NSString,這樣會(huì)形成一個(gè)對(duì)比,方便大家理解

   @property(nonatomic, strong)NSString *testString;

   @property(nonatomic, strong)NSMutableString *test2String;

   @property(nonatomic, copy)NSString *test3String;

   @property(nonatomic, strong)NSMutableString *test4String;

定義好屬性后我們對(duì)其進(jìn)行賦值操作 :

    self.testString = @"aaaa";
    self.test2String  = [[NSMutableString alloc] init];
    self.test2String.string = @"nuli";
    self.testString = _test2String;

    self.test3String = @"bbb";
    NSMutableString *test4String  = [[NSMutableString alloc] init];
    self.test4String = test4String;
    self.test4String.string = [@"fendou" mutableCopy];
    self.test3String = _test4String;

我們首先給testString進(jìn)行了賦值喜滨,然后生成了一個(gè)test2String捉捅,并對(duì)其賦值,然后分別再來看testString和test2String的內(nèi)存地址和值虽风,我們通過打斷點(diǎn)使用lldb來查看,當(dāng)程序執(zhí)行到斷點(diǎn)處的時(shí)候

1.png

![2.png](http://upload-images.jianshu.io/upload_images/4316454-ec471757b6404b7b.png? imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

當(dāng)我們將test2String賦值給testString之后內(nèi)存地址和值如下圖所示:
可以看到兩個(gè)字符串的值和內(nèi)存一樣棒口,這個(gè)時(shí)候我們來改變test2String字符串的值然后在來查看:

5.png

我們會(huì)發(fā)現(xiàn)兩個(gè)字符串的值同時(shí)發(fā)生了改變,但內(nèi)存地址是一致的焰情,所以我們可以肯定兩個(gè)字符串是共用的一份內(nèi)存陌凳,也就是說使用strong來修飾NSString,在你對(duì)其進(jìn)行賦值的時(shí)候内舟,只是復(fù)制了一個(gè)指針而已合敦,并沒有分配新的內(nèi)存空間,這樣的話會(huì)導(dǎo)致一個(gè)什么樣的問題呢验游?就是你在程序的其他地方更改了test2String的值后testString的值也會(huì)發(fā)生改變充岛,所以這個(gè)會(huì)存在潛在的數(shù)據(jù)污染的風(fēng)險(xiǎn),如非明確共用一份內(nèi)存外耕蝉,不建議使用strong來修飾NSString
下面我們來看看使用copy修飾的字符串賦值的時(shí)候是怎么樣的崔梗,請(qǐng)看下圖:當(dāng)程序執(zhí)行到這個(gè)地方的時(shí)候:

7.png
8.png

將test4String的值賦給test3String之后內(nèi)存地址和值如下圖所示:

10.png

可以看到test3String字符串的內(nèi)存和內(nèi)容都沒有發(fā)生改變,改變test3String 的值test4String的地址和內(nèi)容也沒有發(fā)生任何改變垒在,所有我們可以知道使用copy關(guān)鍵字修飾的字符串在賦值的時(shí)候會(huì)重新生成一塊新的內(nèi)存蒜魄,然后把另一個(gè)字符串的內(nèi)容復(fù)制進(jìn)來,這就相當(dāng)于兩個(gè)字符串都存在于兩個(gè)獨(dú)立的內(nèi)存空間,所以改變?nèi)魏我粋€(gè)字符串的值對(duì)另外一個(gè)字符串都不會(huì)有任何的影響谈为,這個(gè)也就是我們所說的深復(fù)制旅挤。

修飾數(shù)組時(shí)其實(shí)也一樣,如下面伞鲫,我定義了兩個(gè)可變數(shù)組:

@property(nonatomic,copy,nullable)NSMutableArray<YCCombineModel *> *historyOrderArray;

- (void)viewDidLoad {
    [super viewDidLoad];
   NSMutableArray  *arr = [NSMutableArray array];
  _historyOrderArray = a;
    for (int i = 0; i<20; i++) {
        YCCombineModel *model = [[YCCombineModel alloc] init];
        model.isSelected = NO;
        [_historyOrderArray addObject:model];
    }
}

當(dāng)我用copy修飾數(shù)組的時(shí)候粘茄,代碼執(zhí)行到

 [_historyOrderArray addObject:model];

這行代碼的時(shí)候會(huì)掛掉,要理解崩潰的原因先要知道一些常識(shí)性的東西:
在iOS開發(fā)中秕脓,對(duì)象之間傳值都是使用引用計(jì)數(shù)器增加的方式柒瓣,這種方式的適用于當(dāng)對(duì)象的某屬性的值改變時(shí),引用該對(duì)象的不同指針會(huì)同時(shí)改變吠架,因?yàn)檫@兩個(gè)指針指向的是同一個(gè)內(nèi)存地址芙贫,當(dāng)一個(gè)指針執(zhí)行的對(duì)象屬性值發(fā)生改變時(shí),不影響另一個(gè)對(duì)象诵肛,那么需要分配兩個(gè)不同的內(nèi)存地址屹培,也就是說,我們就不可以采用retain關(guān)鍵字了怔檩,而是要采用copy 關(guān)鍵字。如:
property (nonatomic,copy)NSSting * name;
一:
區(qū)分深復(fù)制與淺復(fù)制蓄诽,一般只有可變的mutableCopy到mutableCopy的Copy才是淺復(fù)制薛训,不產(chǎn)生副本只是retain count增加。
副本的特點(diǎn):彼此的內(nèi)容一樣,擁有相同的方法,在內(nèi)存中有兩個(gè)對(duì)象.
1.copy
1> 如果對(duì)象有 可變/不可變 版本的區(qū)別, copy方法只能拷貝出不可變的副本.
2> 如果對(duì)象沒有 可變/不可變 版本的區(qū)別,copy方法只是建立一個(gè)副本.

2.mutableCopy
建立對(duì)象的可變版本的副本(如果對(duì)象有 可變/不可變 版本之分)

3.深拷貝/淺拷貝
1>深拷貝:如果建立出新的副本,在內(nèi)存中有兩個(gè)對(duì)象.就是深拷貝.
可變 -> 不可變 (copy)
可變 -> 可變 (mutableCopy)
不可變 -> 可變 (mutableCopy)

2.淺拷貝:不會(huì)建立新的副本, 只是引用計(jì)數(shù)加1.
不可變 -> 不可變 (因?yàn)閮蓚€(gè)不可變對(duì)象誰都不會(huì)被改變,也就沒必要建立副本)

因?yàn)槎x了copy修飾屬性后 在執(zhí)行其setter方法的時(shí)候會(huì)先release掉舊值然后retain 新值仑氛,并且上面那種賦值實(shí)際就相當(dāng)于 _historyOrderArray = [arr copy]; copy后就會(huì)返回一個(gè)NSArray類型的對(duì)象乙埃。所以調(diào)用addObject方法就會(huì)報(bào)unrecognized selector sent to instance 0x14e14970錯(cuò)誤, 但是如果使用strong來修飾_historyOrderArray就相當(dāng)于直接賦值,不會(huì)報(bào)錯(cuò)锯岖。
看完兩個(gè)的對(duì)比之后,我相信你對(duì)字符串和數(shù)組的修飾符的使用有了一個(gè)新的認(rèn)識(shí)。感謝您花費(fèi)寶貴的時(shí)間來閱讀此文益缎!如果有錯(cuò)誤的話歡迎大家多多指點(diǎn)掂名,當(dāng)然有想深入交流的也可以加我微信:bubiandeai05

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市捶牢,隨后出現(xiàn)的幾起案子鸠珠,更是在濱河造成了極大的恐慌,老刑警劉巖秋麸,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渐排,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡灸蟆,警方通過查閱死者的電腦和手機(jī)驯耻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人可缚,你說我怎么就攤上這事霎迫。” “怎么了城看?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵女气,是天一觀的道長。 經(jīng)常有香客問我测柠,道長炼鞠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任轰胁,我火速辦了婚禮谒主,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赃阀。我一直安慰自己霎肯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布榛斯。 她就那樣靜靜地躺著观游,像睡著了一般。 火紅的嫁衣襯著肌膚如雪驮俗。 梳的紋絲不亂的頭發(fā)上懂缕,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音王凑,去河邊找鬼搪柑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛索烹,可吹牛的內(nèi)容都是我干的工碾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼百姓,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼渊额!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起瓣戚,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤端圈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后子库,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舱权,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年仑嗅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宴倍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片张症。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸵贬,靈堂內(nèi)的尸體忽然破棺而出俗他,到底是詐尸還是另有隱情,我是刑警寧澤阔逼,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布兆衅,位于F島的核電站,受9級(jí)特大地震影響嗜浮,放射性物質(zhì)發(fā)生泄漏羡亩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一危融、第九天 我趴在偏房一處隱蔽的房頂上張望畏铆。 院中可真熱鬧,春花似錦吉殃、人聲如沸辞居。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瓦灶。三九已至,卻和暖如春抱完,著一層夾襖步出監(jiān)牢的瞬間倚搬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工乾蛤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捅僵。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓家卖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庙楚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子上荡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

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