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. jquery动态live绑定toggle事件

    $(".btn").live("click",function(){ $(this).toggle( function () { //事件 1 console. ...

  2. Spark-BlockManager

    简单说明 BlockManager是管理整个Spark运行时数据的读写,包含数据存储本身,在数据存储的基础之上进行数据读写.由于Spark是分布式的,所有BlockManager也是分布式的,Bloc ...

  3. 0day学习笔记(3)--修改函数返回地址

    环境: devc++(编译改为32位),windows10 源码(来自书中) #include <stdio.h> #define PASSWORD "1234567" ...

  4. Git基本操作和使用

    基本命令: git config git init git clone git remote git fetch git commit git rebase git push 本地基本操作: git ...

  5. SSL/TLS 漏洞“受戒礼”,RC4算法关闭

    SSL/TLS 漏洞"受戒礼" 一.漏洞分析 事件起因 2015年3月26日,国外数据安全公司Imperva的研究员Itsik Mantin在BLACK HAT ASIA 2015 ...

  6. Linux下解压rar压缩包

    wget http://www.rarlab.com/rar/rarlinux-x64-4.2.0.tar.gz rar软件不需要安装,直接解压到/usr/local下,以下操作需要有root权限. ...

  7. QT 无法抓住异常

    出处:https://stackoverflow.com/questions/40980171/qt5core-dll-crashing I've found that enabling /EHa ( ...

  8. Linux中的常用快捷键

    tab 命令或路径补全键,linux里面最有用的快捷键,如果tab不到路径或命令,就代表没有这个路径或者命令,还有可能是权限不对 ctrl+c 终止当前任务命令或程序 ctrl+d 退出当前用户环境, ...

  9. telnet 636端口不通

    今天发生了一件奇怪的事情,LDAP的636端口突然就不通了报错如下 [www@DC ~]$ telnet 10.219.90.173 636Trying10.219.90.173...Connecte ...

  10. Node Mysql事务处理封装

    node回调函数的方式使得数据库事务貌似并没有像java.php那样编写简单,网上找了一些事务处理的封装并没有达到自己预期的那样简单编写,还是自己封装一个吧.封装的大体思路很简单:函数接受一个事务处理 ...