什么是深拷贝和浅拷贝

浅拷贝:就是指针的复制,拷贝的指针跟原指针指向内存中的同一个位置的对象。至于对象的引用计数值是否+1,就是看拷贝的指针赋给给的变量是Strong类型的,还是week类型的。 如果是 strong类型,那么被拷贝的对象的内存计数值会+1,如果赋值给了weak类型的变量,那么被拷贝的对象的内存计数值会保持不便。

深拷贝:将内存中的对象拷贝一份,放到一个新的位置,并将这个指向这个新位置的指针指赋值给另外一个变量。

判断拷贝类型,关键的依据是指针所指向的对象在内存中的地址。

IOS中的拷贝方式有两种拷贝,一种是 copy ,另外一种是mutableCopy。 至于这两种方法对产生的拷贝属于'浅拷贝'还是'深拷贝'是要根据具体情况来决定的。

1:对于非容器类对象的拷贝。

什么是非容器类对象。 类似于  NSString ,NSNumber 等这种只能存储一个值的对象就叫做非容器类对象。

1.1:非容器类不可变对象的拷贝

    NSString *string = @"非容器类对象";

NSString *stringCopy = [string copy];

NSMutableString *MStringCopy = [string copy];

NSString *stringMutCopy = [string mutableCopy];

NSMutableString *MStringMutCopy = [string mutableCopy];

NSLog(@"对象的地址:%p",string);            //对象的地址:0x107d7e6d8

NSLog(@"对象的地址:%p",stringCopy);         //对象的地址:0x107d7e6d8

NSLog(@"对象的地址:%p",MStringCopy);      //对象的地址:0x107d7e6d8

NSLog(@"对象的地址:%p",stringMutCopy);     //对象的地址:0x7f9f397022e0

NSLog(@"对象的地址:%p",MStringMutCopy);    //对象的地址:0x7f9f395043c0

通过上面的打印结果来分析:

对于非容器类不可变对象:copy是属于浅拷贝,mutableCopy属于深拷贝

为什么会这样呢?

复制之后,IOS也是考虑到了内存控制和变量之间不相互干扰的原则。 对于内存中不可变的对象,因为对象不可变,所以对于使用这个对象的变量来说,指向同一个内存位置,即满足了使用相同的内容,又不必要开辟新内存空间,达到了节省内存空间的目的。

1.2:非容器类可变对象的拷贝

NSMutableString *string = [NSMutableString stringWithString:@"非容器类可变对象"];

NSString *stringCopy = [string copy];

NSMutableString *MStringCopy = [string copy];

NSString *stringMutCopy = [string mutableCopy];

NSMutableString *MStringMutCopy = [string mutableCopy];

NSLog(@"对象的地址:%p",string);       //对象的地址:0x7fc2c9f054a0

NSLog(@"对象的地址:%p",stringCopy);     //对象的地址:0x7fc2c9d08800

NSLog(@"对象的地址:%p",MStringCopy);    //对象的地址:0x7fc2c9d168e0

NSLog(@"对象的地址:%p",stringMutCopy);    //对象的地址:0x7fc2c9c065e0

NSLog(@"对象的地址:%p",MStringMutCopy);   //对象的地址:0x7fc2c9d179b0

可以看到上面的对象在内存中的地址都不相同,也就是说他们发生的拷贝都是深拷贝

总结:

1:对于非容器类不可变对象的拷贝,copy方法属于浅拷贝,mutableCopy属于深拷贝

2:对于非容器类可变对象的拷贝, copy方法属于深拷贝,mutableCopy也属于深拷贝

这样处理的依据是:对象之间的不干扰以及内存节省的原则

2:对于容器类对象的拷贝

什么是容器类对象。就是可以存储其他对象的对象。比如:NSArray,NSDictionary等等

2.1:不可变容器类对象的拷贝

NSArray *ary = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];

NSArray *aryCopy = [ary copy];

NSMutableArray *MAryCopy = [ary copy];

NSArray *aryMCopy = [ary mutableCopy];

NSMutableArray *MAryMCopy = [ary mutableCopy];

NSLog(@"对象的地址:%p",ary);           //0x7fedc25058c0

NSLog(@"对象的地址:%p",aryCopy);        //0x7fedc25058c0

NSLog(@"对象的地址:%p",MAryCopy);       //0x7fedc25058c0

NSLog(@"对象的地址:%p",aryMCopy);       //0x7fedc250b5f0

NSLog(@"对象的地址:%p",MAryMCopy);      //0x7fedc2414310

根据对象在内存中的地址可以,

对于不可变容器类对象为,copy为浅拷贝,mutableCopy为神拷贝

2.2:可变容器类对象的拷贝

NSMutableArray *ary = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];

NSArray *aryCopy = [ary copy];

NSMutableArray *MAryCopy = [ary copy];

NSArray *aryMCopy = [ary mutableCopy];

NSMutableArray *MAryMCopy = [ary mutableCopy];

NSLog(@"对象的地址:%p",ary);            //0x7fe703703d90

NSLog(@"对象的地址:%p",aryCopy);         //0x7fe703706720

NSLog(@"对象的地址:%p",MAryCopy);      //0x7fe703706180

NSLog(@"对象的地址:%p",aryMCopy);      //0x7fe7037061b0

NSLog(@"对象的地址:%p",MAryMCopy);     //0x7fe703706200

通过拷贝后对象在内存中的地址可以看到,对于可变容器类对象的拷贝,不管copy和mutableCopy都是深拷贝。

IOS的浅拷贝和深拷贝的更多相关文章

  1. [转] js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = ...

  2. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

  3. 渐析java的浅拷贝和深拷贝

          首先来看看浅拷贝和深拷贝的定义:       浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝.       深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所 ...

  4. 关于JavaScript的浅拷贝和深拷贝

    在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...

  5. c#中浅拷贝和深拷贝的理解

    c#中拷贝有浅拷贝和深拷贝之分. 例如对象A,其中有值类型字段和引用类型字段: 1.浅拷贝: 对于值类型字段,直接逐位复制到新拷贝的副本对象中,修改副本的字段的值,不会影响源对象中字段的值: 对于引用 ...

  6. C#浅拷贝与深拷贝区别

    也许会有人这样解释C# 中浅拷贝与深拷贝区别: 浅拷贝是对引用类型拷贝地址,对值类型直接进行拷贝. 不能说它完全错误,但至少还不够严谨.比如:string 类型咋说? 其实,我们可以通过实践来寻找答案 ...

  7. 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析

    当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...

  8. js中的浅拷贝和深拷贝

    说说最近所学:浅拷贝和深拷贝也叫做浅克隆和深克隆,深浅主要针对的是对象的"深度",常见的对象都是"浅"的,也就是对象里的属性就是单个的属性,而"深&q ...

  9. 编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]

    前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议13.为类型输出格式化字符串 建议14.正确实现浅拷贝和深 ...

随机推荐

  1. java继承8个题

    1.实现如下类之间的继承关系,并编写Music类来测试这些类. public class Instrument { public void play(){ System.out.println(&qu ...

  2. iOS学习笔记-精华整理

    iOS学习笔记总结整理 一.内存管理情况 1- autorelease,当用户的代码在持续运行时,自动释放池是不会被销毁的,这段时间内用户可以安全地使用自动释放的对象.当用户的代码运行告一段 落,开始 ...

  3. FIREDAC操作SQLITE内存数据库

    SQLite不仅可以把数据库放在硬盘上,还可以放在内存中,经测试,同样条件下数据库放在内存中比放在硬盘上插入记录速度快差不多3倍. 但数据库放在内存中时有如下缺陷: 1.断电或程序崩溃后数据库就会消失 ...

  4. 使用Nginx负载均衡搭建高性能.NETweb应用程序一

    一.遇到的问题 当我们用IIS服务器部署了一个web应用以后,当很多用户高并发访问的时候,客户端响应就会很慢,客户的体验就会很差,由于IIS接受到客户端请求的 时候,就会创建一个线程,当线程达到几千个 ...

  5. LICEcap – 灵活好用,GIF 屏幕录制工具

    LICEcap – 灵活好用,GIF 屏幕录制工具 http://www.appinn.com/licecap/

  6. C#:如何解决WebBrowser.DocumentCompleted事件的多次调用

    关于DocumentCompleted事件,MSDN给出的解释是在文档加载完毕后执行,但是在我的程序中DocumentCompleted却被多次调用,查了一下资料,大概出现了以下几种情况. 1.Web ...

  7. 【地图API】收货地址详解2

    上次讲解的方法是: 在地图中心点添加一个标注,每次拖动地图就获取地图中心点,再把标注的位置设置为地图中心点.可参考教程:http://www.cnblogs.com/milkmap/p/6126424 ...

  8. Entity Framework 6.x Code Frist For Oracle 实践与注意点

    Entity Framework 6.x Code Frist For Oracle 实践与注意点 开发环境 Visual Studio.net 2015/2017 Oracle 11g/12c 数据 ...

  9. [leetcode]Maximum Product Subarray @ Python

    原题地址:https://oj.leetcode.com/problems/maximum-product-subarray/ 解题思路:主要需要考虑负负得正这种情况,比如之前的最小值是一个负数,再乘 ...

  10. 面包板入门电子制作(class1)视频 全套30集高清

    面包板入门电子制作(class1)套件(30集高清) 本套件以电子制作中最基础的元器件在面包板上搭建电路,用启发性的视频教学方式,使学习者熟悉电子电路基础.发挥想像力.在创新设计和制作中学会独立设计和 ...