关于深浅拷贝问题

时间:2022-11-03 19:52:04

(1)针对NSString、NSNumber等非容器类型对象的拷贝 copy、mutableCopy

对于系统的非容器类对象

a、如果对一不可变对象复制,copy是指针复制(浅拷贝)和 mutableCopy 对象复制(深拷贝)

eg: NSString *aString = @"MySting";

NSString *str1 = [aString copy];       // 浅拷贝 指针复制

NSString *str2 = [aString mutableCopy];    // 深拷贝  对象复制(分配新的内存)

b、如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。

需要注意的是:copy就是复制了一个imutable(不可变)的对象,而mutablecopy(可变的)就是复制了一个mutable的对象。

(2)系统的容器类对象  NSArrayNSDictionary等,对于容器类本身,上面讨论的结论也是适用的,需要探讨的是复制后容器内对象的变化。

eg:

    NSMutableString *a = [@"a" mutableCopy];
    NSArray *array1 = [NSArray arrayWithObjects:a,@"b",@"c",nil];
    
    NSArray *arrayCopy1 = [array1 copy];
    //arrayCopy1是和array同一个NSArray对象(指向相同的对象),包括array里面的元素也是指向相同的指针
    NSLog(@"array1 retain count: %lu",[array1 retainCount]);
    NSLog(@"array1 retain count: %lu",[arrayCopy1 retainCount]);
    NSMutableArray *mArrayCopy1 = [array1 mutableCopy];
    [mArrayCopy1 addObject:@"d"];
    [mArrayCopy1 removeObjectAtIndex:0];
    
    NSLog(@"Origin: %@",array1);
    NSLog(@"iCopy: %@",arrayCopy1);
    NSLog(@"mCopy: %@",mArrayCopy1);
    
    [a insertString:@"aa" atIndex:0];
    
    NSLog(@"Origin: %@",array1);
    NSLog(@"iCopy: %@",arrayCopy1);
    NSLog(@"mCopy: %@",mArrayCopy1);

第一次的打印结果为

Origin: (

    a,

    b,

    c

)

iCopy: (

    a,

    b,

    c

)

mCopy: (

    b,

    c,

    d

)


第二次打印结果为:

Origin: (

    aaa,

    b,

    c

)

iCopy: (

    aaa,

    b,

    c

)

mCopy: (

    b,

    c,

   d

)


对比第一第二次的结果可以看出,array里面存储的是对象是指针,当指针指向的对象发生改变的时候,array输出结果就发生了变化

由此可见,对于容器而言,其元素对象始终是指针复制。如果需要元素对象也是对象复制,就需要实现深拷

-如果容器的某一元素是不可变的,那你复制完后该对象仍旧是不能改变的,因此只需要指针复制即可。

NSArray* dArray = [NSKeyedUnarchiver unarchiveObjectWithData:

    [NSKeyedArchiver archivedDataWithRootObject: array]];  // 真正的深拷贝