理解深复制(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
本身进行了内容拷贝,但是里面的字符串对象却没有进行内容拷贝,而是进行的浅复制,那么dataArray2
和dataArray3
里面的对象是共享同一份的。所以才会出现上面的情况。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
一样。
如上图所示,string2
的属性是copy
类型,可以看到是无法被修改的。
因为此时string2
和copystring
的内存地址不一样,修改一个,不会影响另外一个。
上图所示,如果string2
的属性是strong
类型,就可以被修改,如下图所示:
因为此时string2
和copystring
的内存地址都是一样的,修改一个,两个就同时被修改
copy关键字的NSMutableString崩溃
原因:copy
关键字的string
的setter
方法实际上是把参数copy之后再赋值给变量_string
,那么此时变量_string
虽然被申明为NSMutableString
,但是copy
之后,就把 变量_string
变成了不可变的NSString
类型,所以就会出现方法报错,提示对不可变的NSString
使用了NSMutableString
的方法appendString
。
总结
以上就是iOS的深浅拷贝的详细内容,希望本文在大家开发iOS的过程中能有所帮助。