1.前言問題
在開發(fā)中,總是碰到拷貝問題,不過網(wǎng)上能夠把所有的情況都總結(jié)完成的非常少舀武。今天我就總結(jié)下我遇到過的IOS開發(fā)中的拷貝問題拄养。希望能給大家把這個(gè)問題講明白。
2.幾個(gè)拷貝的概念
1)淺拷貝: 淺拷貝就是拷貝指向原來對(duì)象的指針奕剃,使原對(duì)象的引用計(jì)數(shù)+1衷旅,可以理解為創(chuàng)建了一個(gè)指向原對(duì)象的新指針而已,并沒有創(chuàng)建一個(gè)全新的對(duì)象纵朋。
2)深拷貝:指拷貝對(duì)象的具體內(nèi)容柿顶,而內(nèi)存地址是自主分配的,拷貝結(jié)束之后操软,兩個(gè)對(duì)象雖然存的值是相同的嘁锯,但是內(nèi)存地址不一樣,兩個(gè)對(duì)象也互不影響聂薪,互不干涉家乘。(至少有一層是深拷貝)
3)完全深拷貝:在做深拷貝的時(shí)候,我們拷貝的對(duì)象具有多層,每一層我們都需要拷貝對(duì)象,而不是簡(jiǎn)單的指針拷貝。
3.詳解淺拷貝深拷貝
在這方面很多人已經(jīng)總結(jié)過一般對(duì)象的深淺拷貝問題了,在單一對(duì)象進(jìn)行深淺拷貝的問題,有幾個(gè)總結(jié)的比較好的文章:
(詳解iOS的深淺拷貝)[http://www.reibang.com/p/afca814fba36]
(iOS開發(fā) 深拷貝與淺拷貝)[http://www.reibang.com/p/f01d490401f9]
大致上就是探究了一下深淺拷貝的含義,與IOS 一般開發(fā)中如何深淺拷貝
4.完全拷貝
要想對(duì)多層集合對(duì)象進(jìn)行拷貝藏澳,我們需要進(jìn)行完全拷貝仁锯,這里可以使用歸檔和接檔。
NSArray * array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],[NSString stringWithString:@"b"],@"c",nil];
NSArray * deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject: array]];
控制器截圖:
1.trueDeepCopyArray是完全意義上的深拷貝翔悠,而deepCopyArray則不是业崖,對(duì)于deepCopyArray內(nèi)的元素還是淺拷貝
2.[deepCopyArray objectAtIndex:0]因?yàn)樵瓉硎强勺儗?duì)象,還和上面的結(jié)論一樣蓄愁,依舊是深拷貝双炕。
3.用歸檔的方法實(shí)現(xiàn)了真正的元素深拷貝。
當(dāng)對(duì)象中含有自定義對(duì)象時(shí)我們需要對(duì)該類實(shí)現(xiàn)
- (void)encodeWithCoder:(NSCoder *)aCoder和- (id)initWithCoder:(NSCoder *)aDecoder兩個(gè)方法,否則會(huì)crash.
例 person類:
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:self.userName forKey:@"userName"];
[coder encodeObject:self.userReview forKey:@"userReview"];
[coder encodeObject:self.userTime forKey:@"userTime"];
[coder encodeFloat:self.userStarNum forKey:@"userStarNum"];
}
- (id) initWithCoder: (NSCoder *) coder
{
userName = [[coder decodeObjectForKey:@"userName"]copy];
userReview = [[coder decodeObjectForKey:@"userReview"]copy];
userTime = [[coder decodeObjectForKey:@"userTime"]copy];
userStarNum = [coder decodeFloatForKey:@"userStarNum"];
return self;
}