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];
NSMutableArray *array = [NSMutableArray arrayWithObject:element];
id mutableCopyArray = [array mutableCopy];
这一句代码就是浅拷贝,是拷贝了容器自身,返回了一个新的可变数组,指向不同的内存地址。
内部的元素依然是公用的,也就是说,mutableCopyArray[0]也指向element,[mutableCopyArray[0] addObject:***]会影响到array的结果。
id deepMutableCopyArray = [array test_deepMutableCopy];
这一句代码对应的实现是深拷贝,首先它也拷贝了容器自身,返回了一个新的可变数组,指向不同的内存地址。
其次,对内部的元素也进行了拷贝动作,也就是说deepMutableCopyArray[0]是一个新的可变数组,和原来的element是两个数组,修改[deepMutableCopyArray[0] addObject:***]并不会影响到array的结果。
iOS之深拷贝与浅拷贝的更多相关文章
- iOS中深拷贝、浅拷贝和retain的区别
浅拷贝:浅拷贝是对object对象的指针拷贝,让指针指向同一块内存地址,“对象永远只有一个",浅拷贝使对象的引用计数器+1.代码如下: 可以看出不可变字符串的指针指向了同一地址,并没有重新开 ...
- iOS面试-深拷贝和浅拷贝
浅copy:实际上的内存只有一份 任何copy都只是指向这个内存的一个引用 深copy:原始数据有一份 每一个copy的对象不再是引用 而是内容大小一样 内存地址不同的独立对象 系统的非容器类对象 c ...
- iOS 图文并茂的带你了解深拷贝与浅拷贝
一.概念与总结 1.浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针. 浅拷贝就是拷贝指 ...
- 深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS
深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS ios中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying 协议的类可以发送copy消息,遵守NSMutab ...
- iOS深拷贝与浅拷贝
概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 如图详解:
- Objective-C 之深拷贝和浅拷贝
3月箴言 人的思想是了不起的,只要专注于某一项事业,就一定会做出使自己感到吃惊的成绩来.—— 马克·吐温 1.iOS中关于深拷贝和浅拷贝的概念 浅拷贝:浅拷贝并不拷贝对象本身,只是对指向对象的指针进行 ...
- C#设计模式:原型模式(Prototype)及深拷贝、浅拷贝
原型模式(Prototype) 定义: 原型模式:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象.被复制的实例被称为原型,这个原型是可定制的. Prototype Pattern也是一 ...
- Objective-C中的深拷贝和浅拷贝
在Objective-C中对象之间的拷贝分为浅拷贝和深拷贝.说白了,对非容器类的浅拷贝就是拷贝对象的地址,对象里面存的内容仍然是一份,没有新的内存被分配.对非容器类的深拷贝就是重写分配一块内存,然后把 ...
- $.extend()的深拷贝和浅拷贝详细讲解
版权声明:作者原创,转载请注明出处! 语法:jQuery.extend( [deep ], target, object1 [, objectN ] ) 描述: 将两个或更多对象的内容合并到第一个对象 ...
随机推荐
- 【开源】OSharp框架解说系列(2.2):EasyUI复杂布局及数据操作
OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...
- ASP.NET MVC之分部视图和ChildAction(三)
前言 上节我们已经非常清晰并且明确的讲了@Html.ActionLink的作用,这一节我们开始讲讲分部视图以及孩子Action. 话题 在C#中我们知道继承的目的是为了代码的复用,在Web应用程序同样 ...
- 用html5的视频元素所遇到的第一个坑
html5 有一个video标签,这个是被大家所熟知的事情.按照w3c的规范,我认真的写出如下代码: <video preload="auto" controls=" ...
- 让你的Mac支持NTFS
前段时间换成Mac电脑之后,发现有一点不爽,不能在Mac下写入NTFS格式的磁盘,所以就去研究了一下. 解决方法有如下三种. 第一种,直接使用第三方软件,如Paragon NTFS for MAC,T ...
- 史上最详细的iOS之事件的传递和响应机制
前言: 按照时间顺序,事件的生命周期是这样的: 事件的产生和传递(事件如何从父控件传递到子控件并寻找到最合适的view.寻找最合适的view的底层实现.拦截事件的处理)->找到最合适的view后 ...
- 4.羽翼sqlmap学习笔记之Post登录框注入
4.Sqlmap系列教程——post登录框注入注入点: http://xxx.xxx.com/Login.asp 注入方式一: 1.对着注入点使用burp抓包,保存txt格式文件. 2.输入命令: . ...
- Lucene教程
一:简单的示例 1.1:生成索引 1.1.1:Field.Store和Field.Index 1.1.2:为数字生成索引 1.1.3:为索引加权 1.1.4:为日期生成索引 1.2:查询 1.2.1: ...
- JAVA安全模型
作为一种诞生于互联网兴起时代的语言,Java 从一开始就带有安全上的考虑,如何保证通过互联网下载到本地的 Java 程序是安全的,如何对 Java 程序访问本地资源权限进行有限授权,这些安全角度的考虑 ...
- ios7.1 in-house app的发布方法
iOS7.1版本的in-house app必须发布到https站点才能下载安装,原来的连接: itms-services://?action=download-manifest&url=htt ...
- log4net的使用
1.0 下载并引用 log4net.dll 2.0 修改Web.config <configuration> <configSections> <section name ...