<二>Copy和mutableCopy——iOS开发的疑惑

本文详细解析了容器类(如NSArray、NSMutableArray、NSDictionary、NSMutableDictionary等)的浅拷贝和深拷贝概念,重点阐述了不可变对象与可变对象在拷贝过程中的区别,以及如何通过copy与mutableCopy方法实现拷贝操作。
摘要由CSDN通过智能技术生成

        关于copy和mutableCopy的内容多了一些,所以分开两部分写了,上一篇写到的是非容器类的copy和mutableCopy,这篇主要看容器类的copy和mutableCopy。

二、容器类的浅拷贝和深拷贝

        容器类主要是指NSArray和NSMutableArray,NSDictionary和NSMutableDictionary等,这部分的拷贝其实和非容器类的有些相似,不同的地方在于容器内对象的拷贝。

2.1  不可变对象的浅拷贝和深拷贝

        NSArray *array = [NSArray arrayWithObjects:@"a", @"b", @"c", @"d", nil];
        NSArray *arrayCopy = [array copy];
        NSArray *arrayMCopy = [array mutableCopy];
        NSMutableArray *marryCopy = [array copy];
        NSMutableArray *marrayMCopy = [array mutableCopy];
        
        NSLog(@"array--------%p",array);
        NSLog(@"arrayCopy----%p",arrayCopy);
        NSLog(@"arrayMCopy---%p",arrayMCopy);
        NSLog(@"marryCopy----%p",marryCopy);
        NSLog(@"marrayMCopy--%p",marrayMCopy);

2015-09-21 10:34:05.725 CopyAndMutableCopyTest[643:34782] array--------0x1002069c0
2015-09-21 10:34:05.726 CopyAndMutableCopyTest[643:34782] arrayCopy----0x1002069c0
2015-09-21 10:34:05.726 CopyAndMutableCopyTest[643:34782] arrayMCopy---0x100207e80
2015-09-21 10:34:05.726 CopyAndMutableCopyTest[643:34782] marryCopy----0x1002069c0
2015-09-21 10:34:05.727 CopyAndMutableCopyTest[643:34782] marrayMCopy--0x100207ed0

可以看到,对于不可变对象array的拷贝,效果和非容器类的不可变对象一样。

array、arrayCopy和arrayMCopy的内存地址是一样的,说明了[array copy]对array进行了一次浅拷贝,即指针复制,然后赋值给arrayCopy 和arrayMCopy,这两个指针指向的地址是同一个对象。

而marrayCopy和marrayMCopy的地址则和array的地址不同,说明他们是不同的对象,[array mutableCopy]对array进行了一次深拷贝,在内存中开辟一块存储区域用于存放新的对象。

但是要注意,不管对array进行的是copy还是mutableCopy,容器类对象array中的对象都只进行指针复制(浅拷贝)。这里如果不懂,看下面的例子就可以明白了。


2.2  可变对象的浅拷贝和深拷贝

        NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"a"], @"b", @"c", @"d", nil];
        NSArray *arrayCopy = [array copy];
        NSArray *arrayMCopy = [array mutableCopy];
        NSMutableArray *marrayCopy = [array copy];
        NSMutableArray *marrayMCopy = [array mutableCopy];
        
        //打印所有测试对象
        NSLog(@"array--%@", array);
        NSLog(@"arrayCopy--%@", arrayCopy);
        NSLog(@"arrayMCopy--%@", arrayMCopy);
        NSLog(@"marrayCopy--%@", marrayCopy);
        NSLog(@"marrayMCopy--%@", marrayMCopy);
2015-09-21 10:50:01.954 CopyAndMutableCopyTest[667:40305] array--(a,b,c,d)
2015-09-21 10:50:01.955 CopyAndMutableCopyTest[667:40305] arrayCopy--(a,b,c,d)
2015-09-21 10:50:01.955 CopyAndMutableCopyTest[667:40305] arrayMCopy--(a,b,c,d)
2015-09-21 10:50:01.955 CopyAndMutableCopyTest[667:40305] marrayCopy--(a,b,c,d)
2015-09-21 10:50:01.955 CopyAndMutableCopyTest[667:40305] marrayMCopy--(a,b,c,d)        

        //追加array中的第一个可变对象NSMutableString
        NSMutableString *testString = [array objectAtIndex:0];
        [testString appendString:@"tail"];
       
        //打印所有测试对象
        NSLog(@"array--%@", array);
        NSLog(@"arrayCopy--%@", arrayCopy);
        NSLog(@"arrayMCopy--%@", arrayMCopy);
        NSLog(@"marrayCopy--%@", marrayCopy);
        NSLog(@"marrayMCopy--%@", marrayMCopy);
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] array--(atail,b,c,d)
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayCopy--(atail,b,c,d)
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayMCopy--(atail,b,c,d)
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] marrayCopy--(atail,b,c,d)
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] marrayMCopy--(atail,b,c,d) 
       
        //打印所有测试对象的地址
        NSLog(@"array--------%p",array);
        NSLog(@"arrayCopy----%p",arrayCopy);
        NSLog(@"arrayMCopy---%p",arrayMCopy);
        NSLog(@"marryCopy----%p",marrayCopy);
        NSLog(@"marrayMCopy--%p",marrayMCopy);
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] array--------0x100206da0
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayCopy----0x100206fa0
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayMCopy---0x100207a30
2015-09-21 10:50:01.974 CopyAndMutableCopyTest[667:40305] marryCopy----0x100207a80
2015-09-21 10:50:01.974 CopyAndMutableCopyTest[667:40305] marrayMCopy--0x100207ab0


可以看到每个对象的地址都不一样

2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] array--------0x100206da0
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayCopy----0x100206fa0
2015-09-21 10:50:01.956 CopyAndMutableCopyTest[667:40305] arrayMCopy---0x100207a30
2015-09-21 10:50:01.974 CopyAndMutableCopyTest[667:40305] marryCopy----0x100207a80
2015-09-21 10:50:01.974 CopyAndMutableCopyTest[667:40305] marrayMCopy--0x100207ab0

所以如果是对可变对象array进行的拷贝,则不论是对array进行了mutableCopy还是copy,都会产生新的内存地址,所以这时的拷贝都是深拷贝。

但是!这时候数组包含的对象只进行了指针复制。看代码中的例子,如果我讲array中的第一个可变对象[NSMutableString stringWithString:@"a"]

取出放到testString中来,并追加一个tail

        //追加array中的第一个可变对象NSMutableString
        NSMutableString *testString = [array objectAtIndex:0];
        [testString appendString:@"tail"];
那么array中的第一个可变对象的内容就会变成atail。

而根据指针复制的特点(如果还不清楚的请看第一篇),因为arrayCopy、arrayMCopy、marryCopy、marrayMCopy里面的第一个对象都指向同一个地址,所以其内容也会跟着改变,这些arrayCopy、arrayMCopy、marryCopy、marrayMCopy数组的第一个对象都会变成atail。

这就是数组包含的对象是指针复制的解释。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值