NSCopy 和 NSMutableCopy
本文参考其他博客 如有雷同 请勿见怪 ~
NSCopy和NSMutableCopy的区别从以下几个方面来区分
1 系统的非容器对象 这里是指(NSString NSNumber)一类的对象 NSString * string=@"hello"; NSString * stringCopy=[string copy]; NSMutableString * stringMCopy=[string mutableCopy]; [stringMCopy appendString:@"world"]; NSLog(@"%@",string);//(__NSCFConstantString *) $1 = 0x000000010f3c40e0 @"hello" NSLog(@"%@",stringCopy);//(__NSCFConstantString *) $2 = 0x000000010f3c40e0 @"hello" NSLog(@"%@",stringMCopy);//(__NSCFString *) $3 = 0x00007fe4594468a0 @"hello" /**由以上可以看出 string 和stringCopy 指向的是同一块内存区域(又叫apple弱引用 wweak reference) 此时stringCopy 和string 的引用计数为2 而stringMCopy则是我们所说的真正意义上的复制,系统为其分配了新的内存,但是所指向的字符串还是和string所指的一样 总结:如果对一不可变对象复制:copy 是指针复制(浅拷贝) mutableCopy 就是对象复制(深拷贝) **/ NSMutableString * mString=[NSMutableString stringWithString:@"nihao"]; NSString * mStringCopy=[mString copy]; NSMutableString * mStringMCopy=[mString mutableCopy]; NSLog(@"%p",mString);//0x7fd6e251c510 NSLog(@"%p",mStringCopy);//0xa00006f6168696e5 NSLog(@"%p",mStringMCopy);//0x7fd6e251b360 /** 总结:如果对可变对象复制 都是深拷贝(每次内存地址都不一样) **/ 2系统的容器类对象,这里是指(NSArray NSDictionary) 对于容器类本身,上面的讨论结论也是适用的 需要探讨的是复制后容器内对象的变化 NSArray * array1=[NSArray arrayWithObjects:@"a",@"b",@"c", nil]; NSArray * arrayCopy1=[array1 copy]; //arrayCopy1 和array1 是同一个NSArray对象(指向相同的对象) 包括array里面的元素也是指向相同的指针 NSMutableArray * mArrayCopy1=[array1 mutableCopy]; //mArrayCopy1 是array1的可变副本 指向的对象和array1 不同 但是其中的元素和array1 中的元素指向的是同一个对象。mArrayCopy1 还可以自己修改自己的对象 //容器内的元素内容都是指针复制 NSArray * mArray1=[NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil]; NSArray * mArrayCopy2=[mArray1 copy]; NSMutableArray * mArrayMCopy1=[mArray1 mutableCopy]; NSLog(@"%p",mArray1);//0x7f9860727f70 NSLog(@"%p",mArrayCopy2);//0x7f9860727f70 NSLog(@"%p",mArrayMCopy1);//0x7f9860727fa0 NSMutableString * testString=[mArray1 objectAtIndex:0]; [testString appendString:@"tail"]; NSLog(@"%@",mArray1);//atail,b,c NSLog(@"%@",mArrayCopy2);//atail,b,c NSLog(@"%@",mArrayMCopy1);//atail,b,c //总结 对于容器而言,其元素对象始终是指针复制。如果需要元素对象也是对象复制,就需要深拷贝 NSArray * array=[NSArray arrayWithObjects:[NSMutableString stringWithString:@"first"],[NSMutableString stringWithString:@"b"],@"c", nil]; NSArray * deepCopyArray=[[NSArray alloc] initWithArray:array copyItems:YES]; NSArray * trueDeepCopyArray=[NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]]; //trueDeepCopyArray是完全意义上的深拷贝 而deepCopyArray则不是,对于deepCopyArray内的不可变的元素还是指针复制.(ps此处不是太明白 下面例子明明就是深copy啊) NSMutableString * tempString=[array objectAtIndex:0]; [tempString appendString:@"hello"]; NSLog(@"%@",array);//firsthhello,b,c NSLog(@"%@",deepCopyArray);//frist,b,c NSLog(@"%@",trueDeepCopyArray);//firist,b,c
-----------------------------------------------------------------------------------------------------
总结:
对于不可变对象进行操作 Copy是浅复制(指针复制) MutableCopy是深复制(对象复制 内存地址 指针复制)
对于可变对象进行操作 Copy和MutableCopy都是深复制(每次的内存地址都不一样)
Copy对象都是不可变的 MutableCopy是可变的
对于容器类的对象 容器中的对象都是浅复制(指针复制)