iOS copy和mutableCopy区别

今天遇到一个问题,由此引起copy和mutalbeCopy的区别,不深究不觉得自己不知道,随便一问就给问住了。正文开始。

NSArray 和 NSMutableArray 为例

copy是浅拷贝,不拷贝对象本身

1.以下代码会输出什么结果

        NSMutableArray *array = @[@"s",@"3"];
        id a = [array copy];
        id b = [array mutableCopy];
        NSLog(@"%@,%@",a,b);
        
        NSArray *arr2 = @[@"ew",@"e3"];
        id c = [arr2 copy];
        id d = [arr2 mutableCopy];
        NSLog(@"%@,%@",c,d);

        [d addObject:@"5"];

打印结果如下

2019-10-29 15:21:41.618384+0800 debug-objc[86615:17735663] 0x10060e150 a: 0x10060e150, b: 0x10060e3e0
2019-10-29 15:21:46.607998+0800 debug-objc[86615:17735663] 0x10060e440 c: 0x10060e440, d: 0x10060e410
image.png

从上面截图可以看出,

  1. 无论是array还是arr2 和他定义无关,后面的copy操作只和初始化的对象实际的类型有关。
  2. copy浅拷贝,只是把地址指向变了,mutableCopy深拷贝把内存复制了一份。
  3. mutableCopy拷贝结束后的对象实际上是可变数组,可以进行可变数组的插入和删除。
2. 改变copy生成的对象是否会影响原对象
        NSMutableArray *array = @[@"s",@"3"];
        id a = [array copy];
        id b = [array mutableCopy];
        NSLog(@"%p a: %p, b: %p",array, a,b);
        NSLog(@"%@ a: %@, b: %@",array, a,b);
        a = @[@"6",@"8"];
        NSLog(@"%p a: %p, b: %p",array, a,b);
        NSLog(@"%@ a: %@, b: %@",array, a,b);

打印结果如下:


2019-10-29 15:29:50.302258+0800 debug-objc[86919:17744684] 0x10070e0f0 a: 0x10070e0f0, b: 0x10070a520
2019-10-29 15:29:50.302420+0800 debug-objc[86919:17744684] (
    s,
    3
) a: (
    s,
    3
), b: (
    s,
    3
)
2019-10-29 15:29:50.302439+0800 debug-objc[86919:17744684] 0x10070e0f0 a: 0x100574470, b: 0x10070a520
2019-10-29 15:29:50.302527+0800 debug-objc[86919:17744684] (
    s,
    3
) a: (
    6,
    8
), b: (
    s,
    3
)

copy 生成的对象改变,不会影响原来的array变化。mutableCopy更是不影响。

上例中由于list里面存储的是固定字符,在内存中只有一份,所以只会拷贝array层面的内存,那如果替换成对象呢。
       NSArray *array = @[[NSString new],[NSDictionary new]];
        id a = [array copy];
        id b = [array mutableCopy];
        NSLog(@"%p a: %p, b: %p",array, a,b);
        for (int i=0; i<2; i++) {
            NSLog(@"array index %i: %p",i ,array[i]);
            NSLog(@"a index %i: %p",i ,a[i]);
            NSLog(@"b index %i: %p",i ,b[i]);
        }
        b[1] = [NSSet new];
        NSLog(@"array index 1: %p",array[1]);
        NSLog(@"b index 1: %p",b[1]);

打印结果如下


2019-10-29 16:11:36.300122+0800 debug-objc[91397:17797676] 0x10080a3d0 a: 0x10080a3d0, b: 0x10080a4d0
2019-10-29 16:11:36.300138+0800 debug-objc[91397:17797676] array index 0: 0x7fff8fef03e8
2019-10-29 16:11:36.300145+0800 debug-objc[91397:17797676] a index 0: 0x7fff8fef03e8
2019-10-29 16:11:36.300152+0800 debug-objc[91397:17797676] b index 0: 0x7fff8fef03e8
2019-10-29 16:11:36.300158+0800 debug-objc[91397:17797676] array index 1: 0x100701100
2019-10-29 16:11:36.300164+0800 debug-objc[91397:17797676] a index 1: 0x100701100
2019-10-29 16:11:36.300172+0800 debug-objc[91397:17797676] b index 1: 0x100701100
2019-10-29 16:11:36.300185+0800 debug-objc[91397:17797676] array index 1: 0x100701100
2019-10-29 16:11:36.300191+0800 debug-objc[91397:17797676] b index 1: 0x10055dc80

对于array copy 和 mutableCopy对象只能copy第一层的内存地址,array里面的内存地址是没有变化的。

        NSMutableArray *array = [NSMutableArray arrayWithArray:@[[NSString new],[NSDictionary new]]];
        id a = [array copy];
        id b = [array mutableCopy];
        NSLog(@"%p a: %p, b: %p",array, a,b);
        for (int i=0; i<2; i++) {
            NSLog(@"array index %i: %p",i ,array[i]);
            NSLog(@"a index %i: %p",i ,a[i]);
            NSLog(@"b index %i: %p",i ,b[i]);
        }
        b[1] = [NSSet new];
        NSLog(@"array index 1: %p",array[1]);
        NSLog(@"b index 1: %p",b[1]);

打印结果如下:

2019-10-29 16:20:23.955872+0800 debug-objc[91682:17806709] 0x100609d30 a: 0x100704a10, b: 0x10071d4f0
2019-10-29 16:20:23.955896+0800 debug-objc[91682:17806709] array index 0: 0x7fff8fef03e8
2019-10-29 16:20:23.955906+0800 debug-objc[91682:17806709] a index 0: 0x7fff8fef03e8
2019-10-29 16:20:23.955914+0800 debug-objc[91682:17806709] b index 0: 0x7fff8fef03e8
2019-10-29 16:20:23.955920+0800 debug-objc[91682:17806709] array index 1: 0x1006000e0
2019-10-29 16:20:23.955927+0800 debug-objc[91682:17806709] a index 1: 0x1006000e0
2019-10-29 16:20:23.955934+0800 debug-objc[91682:17806709] b index 1: 0x1006000e0
2019-10-29 16:20:23.955948+0800 debug-objc[91682:17806709] array index 1: 0x1006000e0
2019-10-29 16:20:23.955955+0800 debug-objc[91682:17806709] b index 1: 0x10050c010

可变数组的copy和mutableCopy 都会生成一份新的地址,copy生成不可变数组,mutableCopy生成可变数组。也只拷贝了一层。
总结

  • copy修饰NSMutableArray的时候会有内存变化,否则不会,只影响一层。生成的都是不可变数组。
  • mutableCopy修饰NSArray和NSMutableArray都会引起内存变化,只影响一层,并且生成的都是可变数组。
  • copy互不影响的主要原因是因为拷贝之后是NSArray,这样导致只能改变NSArray的指针指向,不能改变array内部元素,当新的copy指针指向别的地方时候内容就会变化,和原来array无关。

你可能感兴趣的:(iOS copy和mutableCopy区别)