国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

詳解iOS的深淺拷貝

2020-07-26 03:17:32
字體:
來源:轉載
供稿:網友

前言

OC對象的三種拷貝方式

OC的對象拷貝有如下三種方式,很多時候我們把深復制和完全復制混為一談,其他他們是有區別的,具體如下

淺復制(shallow copy):在淺復制操作時,對于被復制對象的每一層都是指針復制。

深復制(one-level-deep copy):在深復制操作時,對于被復制對象,至少有一層是深復制。

完全復制(real-deep copy):在完全復制操作時,對于被復制對象的每一層都是對象復制。

兩圖以避之


理解深復制(mutableCopy)

淺復制很簡單,就不演示了,看上面的圖就懂了,只是簡單的指針拷貝,所以改變原對象或者拷貝后的對象,都會影響另外一個對象。

從上圖我們可以看到mutableCopy對于任何對象都是內容復制,也就是說進行了深復制。

上代碼:

  NSMutableArray * dataArray1=[NSMutableArray arrayWithObjects:                [NSMutableString stringWithString:@"1"],                [NSMutableString stringWithString:@"2"],                [NSMutableString stringWithString:@"3"],                [NSMutableString stringWithString:@"4"],                nil                ];  NSMutableArray * dataArray2=[NSMutableArray arrayWithObjects:                [NSMutableString stringWithString:@"one"],                [NSMutableString stringWithString:@"two"],                [NSMutableString stringWithString:@"three"],                [NSMutableString stringWithString:@"four"],                dataArray1,                nil                ];  NSMutableArray * dataArray3;  NSMutableString * mStr;  dataArray3=[dataArray2 mutableCopy];  mStr = dataArray2[0];  [mStr appendString:@"--ONE"];  NSLog(@"dataArray3:%@",dataArray3);  NSLog(@"dataArray2:%@",dataArray2);

輸出如下:

2016-07-31 17:40:30.702 test1[2113:169774] dataArray3:(  "one--ONE",  two,  three,  four,    (    1,    2,    3,    4  ))2016-07-31 17:40:30.703 test1[2113:169774] dataArray2:(  "one--ONE",  two,  three,  four,    (    1,    2,    3,    4  ))

看上面的輸出,我們發現我們改變原數組dataArray2,竟然也會影響深復制后的dataArray3,不是說好的內容復制嗎,為什么會這樣?

這里我們來說說深復制和完全復制的區別

我們知道深復制,就是把原有對象的內容直接克隆一份到新對象,但是這里有一個坑就是他只會復制一層對象,而不會復制第二層甚至更深層次的對象。

代碼dataArray3=[dataArray2 mutableCopy];只是對數組dataArray2本身進行了內容拷貝,但是里面的字符串對象卻沒有進行內容拷貝,而是進行的淺復制,那么dataArray2dataArray3里面的對象是共享同一份的。所以才會出現上面的情況。

單層深復制

那么如何解決上面的問題呢?

可以使用如下代碼

  dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];

輸出如下:

2016-07-31 17:45:48.472 test1[2151:173221] dataArray3:(  one,  two,  three,  four,    (    1,    2,    3,    4  ))2016-07-31 17:45:48.472 test1[2151:173221] dataArray2:(  "one--ONE",  two,  three,  four,    (    1,    2,    3,    4  ))

可以看到dataArray3并沒有被改變,但是別高興的太早,我們再來改改。

代碼如下:

  NSMutableArray * dataArray1=[NSMutableArray arrayWithObjects:                [NSMutableString stringWithString:@"1"],                [NSMutableString stringWithString:@"2"],                [NSMutableString stringWithString:@"3"],                [NSMutableString stringWithString:@"4"],                nil                ];  NSMutableArray * dataArray2=[NSMutableArray arrayWithObjects:                [NSMutableString stringWithString:@"one"],                [NSMutableString stringWithString:@"two"],                [NSMutableString stringWithString:@"three"],                [NSMutableString stringWithString:@"four"],                dataArray1,                nil                ];  NSMutableArray * dataArray3;  NSMutableString * mStr;  dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];  NSMutableArray *mArr = (NSMutableArray *)dataArray2[4];  mStr = mArr[0];  [mStr appendString:@"--ONE"];  NSLog(@"dataArray3:%@",dataArray3);  NSLog(@"dataArray2:%@",dataArray2);

輸出如下:

2016-07-31 17:47:19.421 test1[2174:174714] dataArray3:(  one,  two,  three,  four,    (    "1--ONE",    2,    3,    4  ))2016-07-31 17:47:19.421 test1[2174:174714] dataArray2:(  one,  two,  three,  four,    (    "1--ONE",    2,    3,    4  ))

可以看到深復制又失效了,這是因為dataArray3=[[NSMutableArray alloc]initWithArray:dataArray2 copyItems:YES];僅僅能進行一層深復制,對于第二層或者更多層的就無效了,那怎么辦呢?

別急,我們還有大招沒放。

完全復制

要想對多層集合對象進行復制,我們需要進行完全復制,這里可以使用歸檔和接檔。

實現代碼如下:

  dataArray3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:dataArray2]];

此時輸出如下:

2016-07-31 17:49:55.561 test1[2202:177163] dataArray3:(  one,  two,  three,  four,    (    1,    2,    3,    4  ))2016-07-31 17:49:55.562 test1[2202:177163] dataArray2:(  one,  two,  three,  four,    (    "1--ONE",    2,    3,    4  ))

可以看到dataArray3沒有被dataArray2的修改影響。

類復制

說完了對象的復制,我們來看看如何實現類的復制,因為比較簡單,直接放上代碼

定義類復制

#import <Foundation/Foundation.h>@interface Person : NSObject<NSCopying>@property(strong,nonatomic)NSString *age;@property(strong,nonatomic)NSString *name;@end
#import "Person.h"@implementation Person- (id)copyWithZone:(NSZone *)zone{  Person *person = [[Person allocWithZone:zone] init];  person.age = self.age;  person.name = self.name;  return person;}@end

調用

  Person *person = [[Person alloc]init];    person.age = @"dsdsd";    person.name = @"dsdsdddww";    Person *copyPerson = [person copy];    NSLog(@"%@-----%@",copyPerson.age, copyPerson.name);

可以看到copyPerson的兩個屬性和persona一樣。

@property中的copy關鍵字

在設置NSString類型的屬性的時候,我們最好設置為copy類型,這樣別人使用我們定義的屬性的時候,他不管怎么改動該屬性的賦值,都不會影響我們給該屬性賦的值,為什么呢?

下面我們來看看


如上圖所示,string2的屬性是copy類型,可以看到是無法被修改的。

因為此時string2copystring的內存地址不一樣,修改一個,不會影響另外一個。


上圖所示,如果string2的屬性是strong類型,就可以被修改,如下圖所示:

因為此時string2copystring的內存地址都是一樣的,修改一個,兩個就同時被修改

copy關鍵字的NSMutableString崩潰

原因:

copy關鍵字的stringsetter方法實際上是把參數copy之后再賦值給變量_string,那么此時變量_string雖然被申明為NSMutableString,但是copy之后,就把 變量_string變成了不可變的NSString類型,所以就會出現方法報錯,提示對不可變的NSString使用了NSMutableString的方法appendString

總結

以上就是iOS的深淺拷貝的詳細內容,希望本文在大家開發iOS的過程中能有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 安溪县| 深泽县| 田林县| 泾源县| 柞水县| 新河县| 名山县| 西乌| 寿阳县| 龙胜| 济阳县| 乌拉特后旗| 东至县| 拉萨市| 尖扎县| 崇礼县| 新乐市| 娱乐| 威宁| 额敏县| 灵丘县| 青神县| 安庆市| 科技| 梧州市| 锡林郭勒盟| 康平县| 梅河口市| 泽普县| 分宜县| 小金县| 山东| 贞丰县| 邵阳县| 武定县| 石渠县| 东丽区| 锦屏县| 江孜县| 磐石市| 古蔺县|