查看: 1373|回复: 6

[其他分享] iOS之深拷贝与浅拷贝


16-3-23 09:35:35 | [复制链接]

8

主题

183

帖子

404

积分

牛人

Rank: 3Rank: 3

发表于 16-3-22 10:18:18 | 显示全部楼层 |阅读模式
iOS之深拷贝与浅拷贝




  在最开始,我们需要清楚一些关于内存分配方式的基础知识。


  一般来说分为栈、堆、静态变量存储区、全局变量存储区、代码区。

  前两个大家都懂的。通常将后三个合并称之为静态存储区,存储的是一些全局变量、静态变量、常量、执行代码等。

  在Objective-C中,不可变数组、不可变字典以及一些常量字符串,都是分配在这个区域的,我们先要明确这一点。

  所以在提到深浅拷贝的时候,用NSArray举例子的,只能说对内存分配方式就不清楚,因为对一个不可变数组进行copy操作,它实际上返回的是一个对象,跟深浅拷贝无关,因为都是按照retain来处理的。这也就是很多所谓教程提到的指针拷贝。

  下面先说一下可变拷贝和不可变拷贝,分别遵循NSCopying和NSMutableCopying协议,需要对应实现copyWithZone:方法和mutableCopyWithZone:方法。

  分两种情况来讲,一种是系统容器类,一种是自定义类。

  一、系统容器类。

  例如NSArray、NSDictionary,它们已经实现了上面两个协议。

  对于它们来说,规则很简单,obj2 = [obj1 copy]返回的必然是一个不可变对象,无论obj1是可变对象还是不可变对象。如果obj1是一个不可变对象,那么它们指向同一个对象,也是上一条我提到过的。

  obj2 = [obj1 mutableCopy]返回的必然是一个可变对象,无论obj1是可变对象还是不可变对象。即使obj1也是一个可变对象,它们仍指向不同地址,是两个对象。

  二、自定义类。

  因为copyWithZone:和mutableCopyWithZone:完全由自己来实现,所以代码的不同实现方式,决定了返回对象是什么。

  在demo中Element类的copyWithZone:有注释,感兴趣的可以参考一下。

  极端一点的例子,例如你直接在copyWithZone:方法中return self;那么obj2 = [obj1 copy]相当于obj2 = obj1,只是一个assign,没有做任何其它操作。

  下面着重说一下浅拷贝和深拷贝。

  首先顾名思义,无论是浅拷贝还是深拷贝,都有一个拷贝在里面,那些说浅拷贝相当于retain、什么所谓指针拷贝的,建议还是不要误人子弟了好吧。

  这里我们以NSMutableArray为例

  NSMutableArray *element = [NSMutableArray arrayWithObject: @1];
  1. <p><font size="3">  NSMutableArray *array = [NSMutableArray arrayWithObject:element];</font></p>
  2. <p><font size="3">  id mutableCopyArray = [array mutableCopy];</font></p>
复制代码
  这一句代码就是浅拷贝,是拷贝了容器自身,返回了一个新的可变数组,指向不同的内存地址。

  内部的元素依然是公用的,也就是说,mutableCopyArray[0]也指向element,[mutableCopyArray[0] addObject:***]会影响到array的结果。

  id deepMutableCopyArray = [array test_deepMutableCopy];

  这一句代码对应的实现是深拷贝,首先它也拷贝了容器自身,返回了一个新的可变数组,指向不同的内存地址。

  其次,对内部的元素也进行了拷贝动作,也就是说deepMutableCopyArray[0]是一个新的可变数组,和原来的element是两个数组,修改[deepMutableCopyArray[0] addObject:***]并不会影响到array的结果。



13

主题

207

帖子

468

积分

牛人

Rank: 3Rank: 3

发表于 16-3-22 11:36:01 | 显示全部楼层
留名,学习一下!

19

主题

188

帖子

430

积分

牛人

Rank: 3Rank: 3

发表于 16-3-22 11:39:00 | 显示全部楼层
不错的文章。

61

主题

77

帖子

220

积分

牛人

Rank: 3Rank: 3

发表于 16-3-22 13:10:59 | 显示全部楼层
赞一下!

5

主题

246

帖子

569

积分

大牛

Rank: 4

发表于 16-3-22 14:52:48 | 显示全部楼层
随便逛逛!

47

主题

216

帖子

468

积分

牛人

Rank: 3Rank: 3

发表于 16-3-22 16:44:13 | 显示全部楼层
路过,赞一下!

5

主题

246

帖子

569

积分

大牛

Rank: 4

发表于 16-3-23 09:35:35 | 显示全部楼层
赞一下!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

最新活动

  • 1024程序员节刚过 千锋教育设计学院万圣节海报设计决赛开启

千锋教育公众号

订阅|小黑屋|手机版|千锋教育论坛 ( 京ICP备12003911号-3 )

GMT+8, 20-2-27 16:36 , Processed in 0.277234 second(s), 34 queries .

Powered by Discuz! X3.2

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表