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是可变的

对于容器类的对象 容器中的对象都是浅复制(指针复制)

原文地址:https://www.cnblogs.com/maomixiaohai/p/5723942.html