Copy与mutableCopy的个人理解

1. 相同点

  • 都是将原有对象进行深拷贝(狭义)

    这里的狭义上的深拷贝指的是在不考虑编译器在编译时对不可变对象进行copy时采取的优化策略:即将不可变对象的地址直接赋值给拷贝对象,因为不可变对象无法进行修改,也就不存在拷贝后原值改变的情况,所以为了效率,即不再重新开辟空间,编译器对不可变对象采取了浅拷贝的方式

    浅拷贝 :只是对指针的拷贝,拷贝后两个指针指向同一个内存空间。

    深拷贝 :不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针是指向两个不同地址的指针。

  • 都是为了防止因原对象改变而造成拷贝对象改变的策略

    不可变对象除外

2.不同点

  • 无论是可变对象还是不可变对象进行copy,返回值一律是不可变对象(与被拷贝对象无关)

    可变对象copy后自然会拷贝一个新的地址给不可变类型的拷贝对象(深拷贝),而不可变对象因为优化策略则为浅拷贝

    NSMutableString* mstr=[NSMutableString stringWithString:@"1"];
    NSString *str=[mstr copy]; //将对象copy给不可变对象
    [mstr appendFormat:@"2"];//因为深拷贝,str不会因mstr改变而改变
    NSLog(@"%@",str); //输出1
    NSString* str0=@"1";
    NSMutableString *str1=[str0 copy];
    NSLog(@"%p:%p",str0,str1); //0x100001040:0x100001040 浅拷贝

    tips:当拷贝对象为可变对象时,使用copy会导致crash(在copy后使用append方法试图改变拷贝对象时)

    NSMutableString* mstr0=[NSMutableString stringWithString:@"1"];
    NSMutableString *mstr1=[mstr0 copy]; //将对象copy给可变对象
    [mstr0 appendFormat:@"2"];//因为深拷贝,mstr1不会因mstr0改变而改变
    NSLog(@"%@",str); //输出1
    [mstr1 appendFormat:@"2"];//crash,因为经过copy后mstr1已经变为了不可变对象(多态,NSMutableString是NSString的子类)
  • 无论是可变对象还是不可变对象进行mutableCopy,返回值一律是可变对象(与被拷贝对象无关,且狭义上深拷贝)

    狭义上的深拷贝指的是对于非容器类,而非容器类只是深拷贝容器,而容器内的对象则为指针拷贝(浅拷贝)

    容器类:NSArray、NSDictionary、NSSet

    如果要对容器类进行完全深拷贝,一般使用对象方法:-(id)initWithArray: copyItems:

    tips:当拷贝对象为不可变对象时,使用mutableCopy会将不可变对象改为可变对象

    NSString* str0=@"1";
    NSString *str1=[str0 mutableCopy]; //将对象mutableCopy给不可变对象
    [(NSMutableString *)str1 appendFormat:@"2"];//这里的str已经为可变对象,但编译器因为看不到可变对象的appendFormat方法,所以这里需要强转换为NSMutableString(若str这里不是真正指向可变对象,则会报错,但这里未报错,所以str已经指向了一个可变对象,即深拷贝)
    NSLog(@"%@",str1); //输出12

3.总结

无论是copy还是mutableCopy都可以看作是为了让被拷贝对象与拷贝对象进行分离,互不干扰的一种策略(通过深拷贝实现,虽然有两个例外:编译器优化(其实无影响)和容器类的假深拷贝)。只不过一个返回的是不可变对象,而另一个返回的是可变对象,仅此而已

Copy与mutableCopy的个人理解的更多相关文章

  1. 关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解

    最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/ ...

  2. iOS copy和mutableCopy 整理

    copy 和 mutableCopy 你真的理解吗?最近发现很多面试者基本都不能很好地回答这个问题.所以整理一下. copy和mutableCopy的概念: copy 浅拷贝,不拷贝对象本身,仅仅是拷 ...

  3. 对copy、mutableCopy理解

    Objective - C 中有很多在日常项目中经常用到的常用代码,在这里着重的讲一下关于copy 和 mutableCopy 的区别以及相关用法. Objective - C 中可变对象和不可对象经 ...

  4. 探讨NSString和NSMutableString的内存问题以及copy和MutableCopy两个方法

    NSString: //main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { ...

  5. NSArray和NSMutableArray的copy和MutableCopy

    NSArray: //main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { ...

  6. copy和mutableCopy都是浅拷贝!!!------你被骗了很多年

    所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!! (ps:什么是容器?比如NSArray,NSMutableArray,NSDictionary,NSMutableDiction ...

  7. iOS copy 和 mutableCopy 学习

    (参考 iOS 52个技巧学习心得笔记 第二章 对象 , 消息, 运行期)的对象部分 关于Copy  有个经典问题”大部分的时候NSString的属性都是copy,那copy与strong的情况下到底 ...

  8. Objective-C中的Strong、Copy与MutableCopy

    面试过程中经常被问到ARC中Strong.Copy的区别是什么.普通的回答是:一样.文艺(正确)的回答是:分情况(我擦!WQY#$&Y**%OWEUR) 可以先参考这篇文章http://www ...

  9. 集合使用copy与mutableCopy的区别

    集合(NSArray,NSSet,NSDictionary等)使用copy与mutableCopy的区别是类似的,下面以NSMutableArray.NSArray 为例子验证如下: NSMutabl ...

随机推荐

  1. STM32 i2c通讯失败复位方法

    最近在调研STM32 F10X,准备把公司AVR的MCU项目迁移到STM32上.在调研STM32 i2c这一部分时,在与i2c slave硬件连接断开后,这时再去读/写 i2c slave需要STM3 ...

  2. ES6新增的Map和WeakMap 又是什么玩意?非常详细的解释

    上一篇文章讲了set和weakSet,这节咱就讲Map和weakMap是什么?这两篇文章并没有什么联系,主要知识用法类似而已.嘿嘿,是不是感觉舒服多了. 什么是Map 介绍什么是Map,就不得不说起O ...

  3. linux 磁盘存储和文件系统

    1.磁盘结构 设备文件:关联至一个设备驱动程序,进而能够与之对应硬件设备进行通信 I/O Ports:I/O 设备地址 一切皆文件:open(),read(),write(),close() 设备类型 ...

  4. XSS跨站脚本攻击学习笔记(pikachu)

    颓废了几天,该好好努力了. XSS概述 XSS漏洞是web漏洞中危害较大的漏洞,是一种发生在web前端的漏洞,所以危害的对象也主要是前端用户,XSS可以用来进行钓鱼攻击,前端js挖矿,获取用户cook ...

  5. Python执行Linux cmd命令,获取输出的一种方法,输出是bytes

    import subprocess p = subprocess.Popen('df -lh', stdout=subprocess.PIPE, shell=True) print(p.stdout. ...

  6. D3.js 力导向图的显示优化

    D3.js 作为一个前端,说到可视化除了听过 D3.js 的大名,常见的可视化库还有 ECharts.Chart.js,这两个库功能也很强大,但是有一个共同特点是封装层次高,留给开发者可设计和控制的部 ...

  7. 基于NFS共享存储实现KVM虚拟机动态迁移

    基于NFS共享存储实现KVM虚拟机动态迁移 一:配置环境 二:安装相关的依赖包 三:实现NFS共享存储 四:KVM机配置相同的步骤 五:安装KVM01安装虚拟机 六:实现迁移  实验初始配置:所有主机 ...

  8. Vue学习—— Vuex学习笔记

    组件是Vue最强大的功能之一,而组件实例的作用域是相互独立的,意味着不同组件之间的数据是无法相互使用.组件间如何传递数据就显得至关重要,这篇文章主要是介绍Vuex.尽量以通俗易懂的实例讲述这其中的差别 ...

  9. MySQL数据库的套接字文件和pid文件

    MySQL数据库的套接字文件和pid文件 socket文件:当用Unix域套接字方式进行连接时需要的文件. pid文件:MySQL实例的进程ID文件. MySQL表结构文件:用来存放MySQL表结构定 ...

  10. TX2开启最大功耗模式

    我们移植深度学习模型到Jetson TX2,为了获得更好的指标参数,我们需要将TX2开启最大功耗模式. Jetson TX2 工作模式及相应的CPU和GPU频率: 上电时,默认采用最低功耗模式1,风扇 ...