日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

strong、copy和mutableCopy详解

發(fā)布時(shí)間:2025/3/21 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 strong、copy和mutableCopy详解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

寫在前面

關(guān)于copy、mutableCopy和strong,一直想好好整理整理,但是因?yàn)楦鞣N原因擱置了。今天上班時(shí)發(fā)現(xiàn)老代碼中因?yàn)檫@個(gè)問題出現(xiàn)了一個(gè)特別惡心的大坑,讓我下定決心寫下這篇博文。如果你認(rèn)為自己沒掌握copy相關(guān)知識(shí),建議看看此文,這里會(huì)有你需要的;如果你認(rèn)為自己掌握了copy相關(guān)知識(shí),也建議看看此文,也許這里有你感興趣的東西。

首先和大家回顧一下有關(guān)copy的兩個(gè)概念——淺拷貝(Shallow Copy)和深拷貝(Deep Copy)。

淺拷貝:只拷貝指針,不拷貝內(nèi)容(不用為內(nèi)容分配新的內(nèi)存空間);
深拷貝:同時(shí)拷貝指針和內(nèi)容,即分配一塊新的內(nèi)存,將原內(nèi)容復(fù)制一份到該內(nèi)存中,并生成指向該內(nèi)存的新指針。(這里謝謝@燦爛天空的提醒,原來的解釋可能不太準(zhǔn)確,特此修正)
通俗點(diǎn)解釋就是,已知一條路,通往羅馬,淺拷貝就是新建一條通往這個(gè)羅馬的路。而深拷貝則是選一個(gè)地方,按照原來的羅馬新建一個(gè)(羅馬內(nèi)部包含的所有東西全部照舊的新建,比如家居、文化等等),并修一條通往新羅馬的路,這樣原來羅馬怎么樣就跟新羅馬沒關(guān)系了。

In the case of collection objects, a shallow copy means that a new collection object is created, but the contents of the original collection are not duplicated—only the object references are copied to the new container.

A deep copy duplicates the compound object as well as the contents of all of its contained objects.

四種copy情況

不可變非集合類對(duì)象的copy

直接上代碼:

NSString *immutableStr = @"KFA_test1"; NSString *copyImmutableStr = [immutableStr copy]; NSString *mutableCopyImmutableStr = [immutableStr mutableCopy]; NSLog(@"\\nimmutableStr:%p-%p\\ncopyImmutableStr:%p-%p\\nmutableImmutableStr:%p-%p",immutableStr,&immutableStr,copyImmutableStr,&copyImmutableStr,mutableCopyImmutableStr,&mutableCopyImmutableStr); 復(fù)制代碼

運(yùn)行結(jié)果

immutableStr:0x103426098-0x7fff5c7dba08 copyImmutableStr:0x103426098-0x7fff5c7dba00 mutableImmutableStr:0x7ffd99d34ce0-0x7fff5c7db9f8 復(fù)制代碼

可以發(fā)現(xiàn),對(duì)不可變非集合類對(duì)象進(jìn)行copy時(shí),只拷貝了指針,內(nèi)容不拷貝。對(duì)不可變非集合類對(duì)象進(jìn)行mutableCopy時(shí),同時(shí)拷貝了指針和內(nèi)容。

可變非集合類對(duì)象的copy

照例上代碼:

NSMutableString *mutableStr = [@"KFA_test2" mutableCopy]; NSString *copyImmutableStr = [mutableStr copy]; NSString *mutableCopyImmutableStr = [mutableStr mutableCopy]; NSLog(@"\\nmutableStr:%p-%p\\ncopyImmutableStr:%p-%p\\nmutableImmutableStr:%p-%p",mutableStr,&mutableStr,copyImmutableStr,&copyImmutableStr,mutableCopyImmutableStr,&mutableCopyImmutableStr); 復(fù)制代碼

運(yùn)行結(jié)果:

mutableStr:0x7feb8bc1c940-0x7fff5610fa08 copyImmutableStr:0xa34cf2e0400c1289-0x7fff5610fa00 mutableImmutableStr:0x7feb8bc1f320-0x7fff5610f9f8 復(fù)制代碼

從結(jié)果可以發(fā)現(xiàn),對(duì)可變非集合類對(duì)象進(jìn)行copy和mutableCopy,都同時(shí)拷貝指針和內(nèi)容。

不可變集合類對(duì)象的copy

這里以數(shù)組為例:

NSArray *immutableArr = @[@"KFA_test3"]; NSString *immu = immutableArr.firstObject; NSArray *copyImmutableArr = [immutableArr copy]; NSString *copyImmu = copyImmutableArr.firstObject; NSArray *mutableCopyImmutableArr = [immutableArr mutableCopy]; NSString *mutableCopyImu = mutableCopyImmutableArr.firstObject; NSLog(@"\\nimmutableArr:%p-%p\\ncopyImmutableArr:%p-%p\\nmutableCopyImmutableArr:%p-%p\\nimmu:%p-%p\\ncopyImmu:%p-%p\\nmutableCopyImu:%p-%p",immutableArr,&immutableArr,copyImmutableArr,&copyImmutableArr,mutableCopyImmutableArr,&mutableCopyImmutableArr,immu,&immu,copyImmu,&copyImmu,mutableCopyImu,&mutableCopyImu); 復(fù)制代碼

運(yùn)行結(jié)果:

immutableArr:0x7fa44a7087d0-0x7fff576619d0 copyImmutableArr:0x7fa44a7087d0-0x7fff576619c0 mutableCopyImmutableArr:0x7fa44a703370-0x7fff576619b0 immu:0x1085a0118-0x7fff576619c8 copyImmu:0x1085a0118-0x7fff576619b8 mutableCopyImu:0x1085a0118-0x7fff576619a8 復(fù)制代碼

不難發(fā)現(xiàn),對(duì)不可變集合類對(duì)象進(jìn)行copy時(shí),只拷貝指針,不拷貝內(nèi)容。對(duì)不可變集合類對(duì)象進(jìn)行mutableCopy時(shí),同時(shí)拷貝指針和內(nèi)容,但是這里的內(nèi)容只針對(duì)集合對(duì)象本身,對(duì)于集合內(nèi)的元素只拷貝指針,不拷貝內(nèi)容。

可變集合類對(duì)象的copy

還是以數(shù)組為例:

NSArray *mutableArr = [@[@"KFA_test3"] mutableCopy]; NSString *mu = mutableArr.firstObject; NSArray *copyImmutableArr = [mutableArr copy]; NSString *copyImmu = copyImmutableArr.firstObject; NSArray *mutableCopyImmutableArr = [mutableArr mutableCopy]; NSString *mutableCopyImu = mutableCopyImmutableArr.firstObject; NSLog(@"\\nmutableArr:%p-%p\\ncopyImmutableArr:%p-%p\\nmutableCopyImmutableArr:%p-%p\\nmu:%p-%p\\ncopyImmu:%p-%p\\nmutableCopyImu:%p-%p",mutableArr,&mutableArr,copyImmutableArr,&copyImmutableArr,mutableCopyImmutableArr,&mutableCopyImmutableArr,mu,&mu,copyImmu,&copyImmu,mutableCopyImu,&mutableCopyImu); 復(fù)制代碼

運(yùn)行結(jié)果:

mutableArr:0x7feacbd0d250-0x7fff521409d0 copyImmutableArr:0x7feacbd06ef0-0x7fff521409c0 mutableCopyImmutableArr:0x7feacbd0c2a0-0x7fff521409b0 mu:0x10dac1118-0x7fff521409c8 copyImmu:0x10dac1118-0x7fff521409b8 mutableCopyImu:0x10dac1118-0x7fff521409a8 復(fù)制代碼

我們發(fā)現(xiàn),對(duì)可變集合類對(duì)象進(jìn)行copy和mutableCopy時(shí),都同時(shí)拷貝指針和內(nèi)容。這里的內(nèi)容跟上文一樣只針對(duì)集合對(duì)象本身,對(duì)于集合內(nèi)部的元素只拷貝指針,不拷貝內(nèi)容。

strong和copy

strong和copy下的字符串

先添加兩個(gè)字符串ivar,分別用strong和copy修飾:

@property (nonatomic, strong) NSString *testStrongStr; @property (nonatomic, copy) NSString *testCopyStr; 復(fù)制代碼

然后寫個(gè)測(cè)試方法:

- (void)testCopyAndStrongForString {NSString *immutableStr = @"KFA_test4";self.testStrongStr = immutableStr;self.testCopyStr = immutableStr;NSLog(@"\\nimmutableStr:%@\\nself.testStrongStr:%@\\nself.testCopyStr:%@",immutableStr,self.testStrongStr,self.testCopyStr);immutableStr = @"KFA_test4_change";NSLog(@"\\nimmutableStr:%@\\nself.testStrongStr:%@\\nself.testCopyStr:%@",immutableStr,self.testStrongStr,self.testCopyStr);NSMutableString *mutableStr = [@"KFA_test5" mutableCopy];self.testStrongStr = mutableStr;self.testCopyStr = mutableStr;NSLog(@"\\nmutableStr:%@\\nself.testStrongStr:%@\\nself.testCopyStr:%@",mutableStr,self.testStrongStr,self.testCopyStr);[mutableStr appendString:@"_change"];NSLog(@"\\nmutableStr:%@\\nself.testStrongStr:%@\\nself.testCopyStr:%@",mutableStr,self.testStrongStr,self.testCopyStr); } 復(fù)制代碼

運(yùn)行結(jié)果:

immutableStr:KFA_test4 self.testStrongStr:KFA_test4 self.testCopyStr:KFA_test4 immutableStr:KFA_test4_change self.testStrongStr:KFA_test4 self.testCopyStr:KFA_test4 mutableStr:KFA_test5 self.testStrongStr:KFA_test5 self.testCopyStr:KFA_test5 mutableStr:KFA_test5_change self.testStrongStr:KFA_test5_change self.testCopyStr:KFA_test5 復(fù)制代碼

從結(jié)果可以看出,當(dāng)賦值對(duì)象是不可變的字符串時(shí),strong和copy的效果一樣,因?yàn)楫?dāng)賦值對(duì)象為不可變的字符串時(shí),copy修飾的ivar進(jìn)行拷貝相當(dāng)于上文中的對(duì)不可變對(duì)象進(jìn)行copy,只拷貝指針,不考慮內(nèi)容。但是當(dāng)賦值對(duì)象為可變的字符串時(shí),當(dāng)賦值對(duì)象發(fā)生變化時(shí),strong修飾的ivar會(huì)跟著變,copy修飾的ivar進(jìn)行了拷貝(參考上文中對(duì)可變對(duì)象進(jìn)行copy),所以不會(huì)變。這里可能有同學(xué)會(huì)有疑惑,為什么明明KFA_test4變成了KFA_test4_change,內(nèi)容變了,而self.testStrongStr和self.testCopyStr的內(nèi)容沒變,這是因?yàn)镵FA_test4變成KFA_test4_change只是因?yàn)閕mmutableStr指針進(jìn)行了重指向指向了KFA_test4_change,而內(nèi)容KFA_test4屬于常量,存在棧區(qū),本身并沒有變。所以在修飾字符串時(shí)為了數(shù)據(jù)的安全,建議用copy,而不用strong。

strong和copy下的數(shù)組

同樣,先添加兩個(gè)數(shù)組ivar,分別用strong和copy修飾:

@property (nonatomic, strong) NSArray *testStrongArr; @property (nonatomic, copy) NSArray *testCopyArr; 復(fù)制代碼

另外再創(chuàng)建一個(gè)model類,有一個(gè)number屬性:

@interface KFACopyModel : NSObject@property (nonatomic, copy) NSString *number;@end 復(fù)制代碼

再寫兩個(gè)函數(shù)(等會(huì)測(cè)試方法里會(huì)用到),用來同時(shí)打印三個(gè)數(shù)組(里面的元素):

void KFALog(NSArray *array1, NSArray *array2, NSArray *array3) {NSString *string1 = KFANSStringFromArray(array1);NSString *string2 = KFANSStringFromArray(array2);NSString *string3 = KFANSStringFromArray(array3);NSLog(@"\\n\\%@\\n%@\\n%@",string1,string2,string3); }NSString *KFANSStringFromArray(NSArray *array) {NSMutableString *string = nil;for (NSString *objc in array) {NSString *objcStr = nil;if ([objc isKindOfClass:[NSString class]]) {objcStr = (NSString *)objc;}else if ([objc isKindOfClass:[KFACopyModel class]]) {KFACopyModel *model = (KFACopyModel *)objc;objcStr = model.number;}if (string == nil) {string = [objcStr mutableCopy];}else {[string appendFormat:@"_%@",objcStr];}}return string; } 復(fù)制代碼

然后就是測(cè)試方法了:

- (void)testCopyAndStrongForArray {NSArray *immutableArr = @[@"KFA_test6"];self.testStrongArr = immutableArr;self.testCopyArr = immutableArr;KFALog(immutableArr,self.testStrongArr,self.testCopyArr);immutableArr = @[@"KFA_test6_change"];KFALog(immutableArr,self.testStrongArr,self.testCopyArr);NSMutableArray *mutableArr = [@[@"KFA_test7"] mutableCopy];self.testStrongArr = mutableArr;self.testCopyArr = mutableArr;KFALog(mutableArr, self.testStrongArr, self.testCopyArr);[mutableArr replaceObjectAtIndex:0 withObject:@"KFA_test7_change"];KFALog(mutableArr, self.testStrongArr, self.testCopyArr);KFACopyModel *model1 = [[KFACopyModel alloc] init];model1.number = @"13789892310";NSArray *immutableArr_ = @[model1];self.testStrongArr = immutableArr_;self.testCopyArr = immutableArr_;KFALog(immutableArr_, self.testStrongArr, self.testCopyArr);model1.number = @"137****2310";KFALog(immutableArr_, self.testStrongArr, self.testCopyArr);KFACopyModel *model2 = [[KFACopyModel alloc] init];model2.number = @"13982650942";NSArray *mutableArr_ = @[model2];self.testStrongArr = mutableArr_;self.testCopyArr = mutableArr_;KFALog(mutableArr_, self.testStrongArr, self.testCopyArr);model2.number = @"139****0942";KFALog(mutableArr_, self.testStrongArr, self.testCopyArr); } 復(fù)制代碼

運(yùn)行結(jié)果:

KFA_test6 KFA_test6_change KFA_test6 KFA_test6 KFA_test7 KFA_test7 KFA_test7 KFA_test7_change KFA_test7_change KFA_test7 13789892310 13789892310 13789892310 137****2310 137****2310 137****2310 13982650942 13982650942 13982650942 139****0942 139****0942 139****0942 復(fù)制代碼

我們發(fā)現(xiàn)一個(gè)有意思的問題,當(dāng)數(shù)組里元素為字符串時(shí),結(jié)果跟咱們預(yù)料的一樣的,但是當(dāng)數(shù)組的元素為KFACopyModel對(duì)象時(shí),結(jié)果跟咱們預(yù)料有點(diǎn)出入了。這里就得回到上文說的四種情況了。對(duì)集合類對(duì)象進(jìn)行copy和mutableCopy時(shí),即便拷貝內(nèi)容,拷貝的也是集合對(duì)象本身,對(duì)于集合內(nèi)的元素只拷貝了指針,不拷貝內(nèi)容。所以當(dāng)數(shù)組里的元素KFACopyModel對(duì)象的number屬性發(fā)生變化時(shí),拷貝的數(shù)組里元素也會(huì)跟著變化。

寫在最后

通過上文我們可以總結(jié)兩點(diǎn):

  • 對(duì)于凡是具有可變子類的類,如NSString有子類NSMutableString,NSArray有子類NSMutableArray,都用copy進(jìn)行修飾,不用strong。但是對(duì)可變類,如NSMutableArray,應(yīng)該用strong,不用copy,不然就會(huì)造成明明定義一個(gè)可變數(shù)組卻不能調(diào)用可變數(shù)組的方法的后果。
  • 給數(shù)組ivar賦值時(shí),為了數(shù)組的安全,最好用一個(gè)臨時(shí)的數(shù)組對(duì)象(此對(duì)象不會(huì)在其他地方用到),更不能用一個(gè)數(shù)組ivar來給另一個(gè)數(shù)組ivar賦值。

本文用的代碼全在這里,可以點(diǎn)擊下載。歡迎拍磚和轉(zhuǎn)發(fā)。

總結(jié)

以上是生活随笔為你收集整理的strong、copy和mutableCopy详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美偷拍一区二区 | av 日韩 人妻 黑人 综合 无码 | 国产肥老妇视频 | 亚洲国产精品成人午夜在线观看 | 男女黄色网| 国产9区 | 亚洲欧洲一区二区三区 | 69xxxx国产| 毛片在线免费 | 在线你懂的视频 | 婷婷伊人综合 | 国产情侣久久久久aⅴ免费 caoporn成人 | 久久久久亚洲无码 | www.日日操| 亚洲三区在线播放 | 亚洲综合一区在线 | 毛片基地视频 | a天堂在线 | 欧美日本三级 | 丰满人妻一区二区三区53视频 | 亚洲AV无码成人精品区东京热 | 亚洲综合色婷婷 | 亚洲特黄特色 | 日韩精品久久久久久 | 波多野结衣电影在线播放 | 麻豆chinese新婚xxx | 国产chinesehd精品露脸 | 一区二区在线观看免费 | 精品视频一区二区三区四区五区 | 精品1区2区3区 | 日本大尺度吃奶做爰久久久绯色 | 456亚洲影院| 国产老女人乱淫免费可以 | av中文字 | 亚洲最大网 | 97无码精品人妻 | 操皮视频 | 极品美女无套呻吟啪啪 | 美女激情网 | 国产视频网 | 国产精品无码一区二区三区 | 免费看美女隐私网站 | 欧美高清不卡 | 西野翔夫の目の前で犯在线 | 欧美午夜三级 | 亚洲欧美bt| 中文字幕高清一区 | 欧美中文字幕在线观看 | 欧美日韩视频无码一区二区三 | 国产精品有码 | 国产伦理片在线观看 | 91精品婷婷国产综合久久蝌蚪 | 亚洲欧美日韩国产 | 日韩欧美在线观看一区二区 | 精品国产一级久久 | 日日躁夜夜躁狠狠躁 | 玉米地疯狂的吸允她的奶视频 | 伊人蕉久影院 | 内射中出日韩无国产剧情 | 成人亚洲综合 | 久久久成人精品一区二区三区 | 日本女优一区 | 青青青手机视频在线观看 | 欧美三级影院 | 国产日产久久高清欧美一区 | 亚洲精品91| 中文字幕日本人妻久久久免费 | 欧美七区 | 欧美成人极品 | 欧美综合成人 | 91精品国产综合久久久密臀九色 | 国产色视频一区二区三区qq号 | 新国产视频 | 黑人导航 | 狠狠艹av| 玖玖精品| 国产成人亚洲欧洲在线 | 国产 日韩 欧美 综合 | 国产精品 欧美精品 | 亚洲成熟女性毛茸茸 | 亚洲成人精选 | 操伊人 | 欧美综合亚洲图片综合区 | 中文字幕视频在线观看 | 美女的胸给男人玩视频 | 国产一区二区三区四区五区六区 | 久久久久国产综合av天堂 | 日韩极品视频在线观看 | 久久国产色av免费观看 | 性色在线观看 | 91超薄肉色丝袜交足高跟凉鞋 | 精品国产一区二区三区四 | 欧美国产精品一区二区三区 | 成人精品福利 | 在线视频一区二区三区四区 | 偷拍自拍一区 | 欧美美女一区 | 国偷自产视频一区二区久 | 三级黄色片免费观看 |