
1.導(dǎo)言
1).本文目標(biāo):為從事iOS開發(fā)的朋友介紹對(duì)象拷貝的使用場(chǎng)景
2).目標(biāo)用戶:初級(jí)或中級(jí)iOS開發(fā)者
2.什么是copy和mutableCopy
copy,又名淺拷貝:只是復(fù)制對(duì)象的引用,并沒有復(fù)制對(duì)象的具體內(nèi)容。
mutableCopy,又名深拷貝:復(fù)制了對(duì)象的具體內(nèi)容,并返回對(duì)象副本的引用。
進(jìn)一步解釋可以這樣去理解:copy方法可以復(fù)制可變對(duì)象或不可變對(duì)象的不可變副本,對(duì)于不可變對(duì)象副本,其對(duì)象的值不可以改變。
mutableCopy方法可以復(fù)制可變對(duì)象或不可變對(duì)象的可變副本,對(duì)于可變對(duì)象副本其對(duì)象是可變的。
3.什么場(chǎng)景下使用二者
舉個(gè)例子,實(shí)際項(xiàng)目中,有個(gè)對(duì)象,在兩個(gè)不同的函數(shù)中使用了,而這兩個(gè)函數(shù)有可能不是互相等待執(zhí)行完后再執(zhí)行下一個(gè)。
-(void)sync
{
[self test1:對(duì)象];
異步執(zhí)行[self test2:對(duì)象];
}
-(void)test1:(對(duì)象);
-(void)test2:(對(duì)象);
以上幾個(gè)函數(shù),在sync中分別調(diào)用了test1和test2,而這兩個(gè)函數(shù)都是直接對(duì)某個(gè)對(duì)象直接做了處理。如果sync沒有加鎖,多次調(diào)用后,由于test2是異步執(zhí)行的,特test1和test2中如果都對(duì)對(duì)象做了類似remove數(shù)組等的操作,此時(shí)同一個(gè)對(duì)象就有可能產(chǎn)生crash現(xiàn)象,或者與預(yù)期結(jié)果不一樣。
這種情況下,最好的方式就是使用mutableCopy方法,深度拷貝對(duì)象,互不干擾。
4.具體實(shí)踐
1.不可變的字符串的copy
NSString*str =@"test1";
NSString*copyStr = [str copy];
NSLog(@"str = %s copyStr= %s",str,copyStr);
NSLog(@"指針地址:str = %@ copyStr= %@",&str,?Str);
輸出結(jié)果:str =0x113d94034 copyStr=0x113d94034
指針地址:str =0x8fee679e7ba4 copyStr=0x8fee679e7bf3
由此得到對(duì)于不可變的字符串的copy,對(duì)象的內(nèi)存地址沒有改變,而是指針的地址改變了。
2.可變的字符串的copy
相同的方式我們對(duì)NSMutableString進(jìn)行copy,會(huì)得到以下結(jié)論:
對(duì)于可變字符串的copy,直接拷貝了對(duì)象。
3.不可變字符串的mutableCopy
我們對(duì)NSString對(duì)象進(jìn)行mutableCopy,默認(rèn)進(jìn)行了深拷貝。
4.可變字符串的mutableCopy
我們對(duì)NSMutableString對(duì)象進(jìn)行mutableCopy,會(huì)進(jìn)行深拷貝。
5.總結(jié)
此外對(duì)自定義對(duì)象的copy與mutableCopy,大家可以去嘗試,網(wǎng)上有很多資料供大家參考。在項(xiàng)目實(shí)際開發(fā)過(guò)程中,針對(duì)不對(duì)的需求,巧妙使用這兩個(gè)方法,可以達(dá)到事半功倍的效果。