用@property聲明的NSString(或NSArray魄缚,NSDictionary)經(jīng)常使用copy關(guān)鍵字,為什么焚廊?如果改用strong關(guān)鍵字冶匹,可能造成什么問題?

  1. 因?yàn)楦割愔羔樋梢灾赶蜃宇悓?duì)象,使用 copy 的目的是為了讓本對(duì)象的屬性不受外界影響,使用 copy 無(wú)論給我傳入是一個(gè)可變對(duì)象還是不可對(duì)象,我本身持有的就是一個(gè)不可變的副本.
  2. 如果我們使用是 strong ,那么這個(gè)屬性就有可能指向一個(gè)可變對(duì)象,如果這個(gè)可變對(duì)象在外部被修改了,那么會(huì)影響該屬性.
copy 此特質(zhì)所表達(dá)的所屬關(guān)系與 strong 類似节值。然而設(shè)置方法并不保留新值徙硅,而是將其“拷貝” (copy)榜聂。 
當(dāng)屬性類型為 NSString 時(shí)搞疗,經(jīng)常用此特質(zhì)來(lái)保護(hù)其封裝性,因?yàn)閭鬟f給設(shè)置方法的新值有可能指向一個(gè) NSMutableString 類的實(shí)例。
這個(gè)類是 NSString 的子類匿乃,表示一種可修改其值的字符串桩皿,此時(shí)若是不拷貝字符串,那么設(shè)置完屬性之后幢炸,字符串的值就可能會(huì)在對(duì)象不知情的情況下遭人更改泄隔。
所以,這時(shí)就要拷貝一份“不可變” (immutable)的字符串宛徊,確保對(duì)象中的字符串值不會(huì)無(wú)意間變動(dòng)佛嬉。
只要實(shí)現(xiàn)屬性所用的對(duì)象是“可變的” (mutable),就應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份闸天。

舉例說明:
定義一個(gè)以 strong 修飾的 array:

@property (nonatomic ,readwrite, strong) NSArray *array;

然后進(jìn)行下面的操作:

 NSMutableArray *mutableArray = [[NSMutableArray alloc] init]; 
 NSArray *array = @[ @1, @2, @3, @4 ]; 
 self.array = mutableArray;
 [mutableArray removeAllObjects];
 NSLog(@"%@",self.array);
 [mutableArray addObjectsFromArray:array];
 self.array = [mutableArray copy];
 [mutableArray removeAllObjects];
 NSLog(@"%@",self.array);

打印結(jié)果如下所示:

2015-09-27 19:10:32.523 CYLArrayCopyDmo[10681:713670] ()
2015-09-27 19:10:32.524 CYLArrayCopyDmo[10681:713670] ( 1, 2, 3, 4)

為了理解這種做法暖呕,首先要知道,兩種情況:

  1. 對(duì)非集合類對(duì)象的 copy 與 mutableCopy 操作苞氮;

  2. 對(duì)集合類對(duì)象的 copy 與 mutableCopy 操作湾揽。

  3. 對(duì)非集合類對(duì)象的copy操作:
    在非集合類對(duì)象中:對(duì) immutable 對(duì)象進(jìn)行 copy 操作,是指針復(fù)制笼吟,mutableCopy 操作時(shí)內(nèi)容復(fù)制库物;對(duì) mutable 對(duì)象進(jìn)行 copy 和 mutableCopy 都是內(nèi)容復(fù)制。用代碼簡(jiǎn)單表示如下:

[immutableObject copy] // 淺復(fù)制
[immutableObject mutableCopy] //深復(fù)制
[mutableObject copy] //深復(fù)制
[mutableObject mutableCopy] //深復(fù)制

比如以下代碼:

NSMutableString *string = [NSMutableString stringWithString:@"origin"];//copy
NSString *stringCopy = [string copy];

查看內(nèi)存贷帮,會(huì)發(fā)現(xiàn) string戚揭、stringCopy 內(nèi)存地址都不一樣,說明此時(shí)都是做內(nèi)容拷貝撵枢、深拷貝毫目。即使你進(jìn)行如下操作:

[string appendString:@"origion!"]

stringCopy 的值也不會(huì)因此改變,但是如果不使用 copy诲侮,stringCopy 的值就會(huì)被改變镀虐。 集合類對(duì)象以此類推。 所以用 @property 聲明 NSString沟绪、NSArray刮便、NSDictionary 經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?duì)應(yīng)的可變類型:NSMutableString绽慈、NSMutableArray恨旱、NSMutableDictionary,他們之間可能進(jìn)行賦值操作坝疼,為確保對(duì)象中的字符串值不會(huì)無(wú)意間變動(dòng)搜贤,應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份。

  1. 集合類對(duì)象的copy與mutableCopy集合類對(duì)象是指 NSArray钝凶、NSDictionary仪芒、NSSet ... 之類的對(duì)象。下面先看集合類immutable對(duì)象使用 copy 和 mutableCopy 的一個(gè)例子:
NSArray *array = @[@[@"a", @"b"], @[@"c", @"d"]];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];

查看內(nèi)容,可以看到 copyArray 和 array 的地址是一樣的掂名,而 mCopyArray 和 array 的地址是不同的据沈。說明 copy 操作進(jìn)行了指針拷貝,mutableCopy 進(jìn)行了內(nèi)容拷貝饺蔑。但需要強(qiáng)調(diào)的是:此處的內(nèi)容拷貝锌介,僅僅是拷貝 array 這個(gè)對(duì)象,array 集合內(nèi)部的元素仍然是指針拷貝猾警。這和上面的非集合 immutable 對(duì)象的拷貝還是挺相似的孔祸,那么mutable對(duì)象的拷貝會(huì)不會(huì)類似呢?我們繼續(xù)往下发皿,看 mutable 對(duì)象拷貝的例子:

NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];

查看內(nèi)存融击,如我們所料,copyArray雳窟、mCopyArray和 array 的內(nèi)存地址都不一樣尊浪,說明 copyArray、mCopyArray 都對(duì) array 進(jìn)行了內(nèi)容拷貝封救。同樣拇涤,我們可以得出結(jié)論:
在集合類對(duì)象中,對(duì) immutable 對(duì)象進(jìn)行 copy誉结,是指針復(fù)制鹅士, mutableCopy 是內(nèi)容復(fù)制;對(duì) mutable 對(duì)象進(jìn)行 copy 和 mutableCopy 都是內(nèi)容復(fù)制惩坑。但是:集合對(duì)象的內(nèi)容復(fù)制僅限于對(duì)象本身掉盅,對(duì)象元素仍然是指針復(fù)制。用代碼簡(jiǎn)單表示如下:

[immutableObject copy] // 淺復(fù)制
[immutableObject mutableCopy] //單層深復(fù)制
[mutableObject copy] //單層深復(fù)制
[mutableObject mutableCopy] //單層深復(fù)制

這個(gè)代碼結(jié)論和非集合類的非常相似以舒。
參考鏈接:iOS 集合的深復(fù)制與淺復(fù)制

摘自這里趾痘,點(diǎn)擊查看更多問題及答案

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蔓钟,隨后出現(xiàn)的幾起案子永票,更是在濱河造成了極大的恐慌,老刑警劉巖滥沫,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件侣集,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡兰绣,警方通過查閱死者的電腦和手機(jī)世分,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缀辩,“玉大人臭埋,你說我怎么就攤上這事踪央。” “怎么了斋泄?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵杯瞻,是天一觀的道長(zhǎng)镐牺。 經(jīng)常有香客問我炫掐,道長(zhǎng),這世上最難降的妖魔是什么睬涧? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任募胃,我火速辦了婚禮,結(jié)果婚禮上畦浓,老公的妹妹穿的比我還像新娘痹束。我一直安慰自己,他們只是感情好讶请,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布祷嘶。 她就那樣靜靜地躺著,像睡著了一般夺溢。 火紅的嫁衣襯著肌膚如雪论巍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天风响,我揣著相機(jī)與錄音嘉汰,去河邊找鬼。 笑死状勤,一個(gè)胖子當(dāng)著我的面吹牛鞋怀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播持搜,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼密似,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了葫盼?” 一聲冷哼從身側(cè)響起辛友,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剪返,沒想到半個(gè)月后废累,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脱盲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年邑滨,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钱反。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掖看,死狀恐怖匣距,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情哎壳,我是刑警寧澤毅待,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站归榕,受9級(jí)特大地震影響尸红,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜刹泄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一外里、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧特石,春花似錦盅蝗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至逞敷,卻和暖如春狂秦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背兰粉。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工故痊, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玖姑。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓愕秫,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親焰络。 傳聞我的和親對(duì)象是個(gè)殘疾皇子戴甩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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