博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
copy与mutableCopy
阅读量:6963 次
发布时间:2019-06-27

本文共 6375 字,大约阅读时间需要 21 分钟。

 

copy就是复制得到一个不可变的对象,mutableCopy就是复制得到一个可变的对象。按照不同情况,以下分别举例说明:

 

1. 对非容器类对象的拷贝(比如 NSString,NSMutableString)

  (1)被拷贝对象本身不可变(如NSString),代码展示请往下看: 

    从以下代码输出内容可以看出:

         1.将A直接赋值给B时=>A和B拥有相同的内存地址,其值当然也相同;但A(或B)被重新赋值后,A(或B)拥有了新的内存地址,值也相应改变,然而这样的改变不会影响另一方B(或A),另一方仍然具有跟之前一样的地址和值。

      2.将A copy到B时=>A和B拥有相同的内存地址,且当A被重新赋值后,A拥有了新的内存地址,其值也相应改变,但这样的改变不会影响B,B仍然具有跟之前一样的地址和值。

      3.将A mutableCopy到B时=>B的地址和A的不相同,B的值可以被重新设定(是setString,而不是指赋值);且A被重新赋值也不会影响B,同样B的改变也不会影响A。

     代码从这里开始++++++++++++++++++++++++++++++++++++++++++++++++++

           NSLog(@"##############以不可变字符串为原型##########");

           NSString *strFirst = @"abc";

           NSLog(@"1.strFirst address : %p; %@",strFirst, strFirst);    

           NSString *strSecond = strFirst;

           NSLog(@"2.strSecond address : %p; %@",strSecond, strSecond);    

           NSString *strFirstCopy = [strFirst copy];//相当于strFirst所指向的地址引用计数+1(地址一样)

           NSLog(@"3.strFirstCopy address : %p; %@",strFirstCopy, strFirstCopy);    

           NSString *strFirstMutableCopy = [strFirst mutableCopy];

           NSLog(@"4.strFirstMutableCopy address : %p; %@",strFirstMutableCopy, strFirstMutableCopy);    

           strFirst = @"bcd";//赋值相当于重新分配地址  

           NSLog(@"5.strFirst address : %p; %@",strFirst, strFirst);

           NSLog(@"5.strSecond address : %p; %@",strSecond, strSecond);//

           NSLog(@"5.strFirstCopy address : %p; %@",strFirstCopy, strFirstCopy);

           NSLog(@"5.strFirstMutableCopy address : %p; %@",strFirstMutableCopy, strFirstMutableCopy);

      对于以上示例代码的控制台输出如下:      

         2016-04-28 13:46:33.504 copyTest[4299:93432] ##############以不可变字符串为原型##########

         2016-04-28 13:46:33.504 copyTest[4299:93432] 1.strFirst address : 0x10244b0e8; abc

         2016-04-28 13:46:33.504 copyTest[4299:93432] 2.strSecond address : 0x10244b0e8; abc 

         2016-04-28 13:46:33.505 copyTest[4299:93432] 3.strFirstCopy address : 0x10244b0e8; abc

         2016-04-28 13:46:33.505 copyTest[4299:93432] 4.strFirstMutableCopy address : 0x7f9882c1d410; abc

         2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirst address : 0x10244b188; bcd

         2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strSecond address : 0x10244b0e8; abc

         2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirstCopy address : 0x10244b0e8; abc

         2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strFirstMutableCopy address : 0x7f9882c1d410; abc

 

  (2)被拷贝对象本身可变(如NSMutableString),代码展示请往下看:

    从以下代码输出内容可以看出:

         1.将A直接赋值给B时=>A和B拥有相同的内存地址,其值当然也相同;当A(或B)被重新设定(是setString,而不是指赋值),另一方值也会跟着改变;但A(或B)被重新赋值后,A(或B)拥有了新的内存地址,值也相应改变,然而这样的改变不会影响另一方B(或A),另一方仍然具有跟之前一样的地址和值。

      2.将A copy到B时=>B跟A的地址不同,且B不能被重新设定值(setString),A的改变不会影响B,B的改变也不影响A。

      3.将A mutableCopy到B时=>B的地址和A的不相同,B的值也可以被重新设定(是setString,而不是指赋值);且A被重新赋值也不会影响B,同样B的改变也不会影响A。

    代码从这里开始++++++++++++++++++++++++++++++++++++++++++++++++++

        NSLog(@"##############以可变字符串为原型###########");

            NSMutableString *strVFirst = [NSMutableString stringWithString:@"a"];

            NSLog(@"1.strVFirst address : %p; %@",strVFirst, strVFirst);    

                NSMutableString *strVSecond = strVFirst;

            NSLog(@"2.strVSecond address : %p; %@",strVSecond, strVSecond);    

            NSMutableString *strVFirstCopy = [strVFirst copy];

            NSLog(@"3.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);    

            NSMutableString *strVFirstMutableCopy = [strVFirst mutableCopy];

            NSLog(@"4.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);    

            [strVFirst setString:@"b"];

            NSLog(@"5.strVFirst address : %p; %@",strVFirst, strVFirst);

            NSLog(@"5.strVSecond address : %p; %@",strVSecond, strVSecond);

            NSLog(@"5.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);

            NSLog(@"5.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);    

            [strVSecond setString:@"c"];

            NSLog(@"6.strVFirst address : %p; %@",strVFirst, strVFirst);

            NSLog(@"6.strVSecond address : %p; %@",strVSecond, strVSecond);

            NSLog(@"6.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);

            NSLog(@"6.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);   

            [strVFirstMutableCopy setString:@"c"];

            NSLog(@"7.strVFirst address : %p; %@",strVFirst, strVFirst);

            NSLog(@"7.strVSecond address : %p; %@",strVSecond, strVSecond);

            NSLog(@"7.strVFirstCopy address : %p; %@",strVFirstCopy, strVFirstCopy);

            NSLog(@"7.strVFirstMutableCopy address : %p; %@",strVFirstMutableCopy, strVFirstMutableCopy);

      对于以上示例代码的控制台输出如下:

        2016-04-28 13:46:33.505 copyTest[4299:93432] ##############以可变字符串为原型###########

        2016-04-28 13:46:33.505 copyTest[4299:93432] 1.strVFirst address : 0x7f9882f99080; a

        2016-04-28 13:46:33.505 copyTest[4299:93432] 2.strVSecond address : 0x7f9882f99080; a

        2016-04-28 13:46:33.505 copyTest[4299:93432] 3.strVFirstCopy address : 0xa000000000000611; a

        2016-04-28 13:46:33.505 copyTest[4299:93432] 4.strVFirstMutableCopy address : 0x7f9882f990c0; a

        2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirst address : 0x7f9882f99080; b

        2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVSecond address : 0x7f9882f99080; b

        2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirstCopy address : 0xa000000000000611; a

        2016-04-28 13:46:33.505 copyTest[4299:93432] 5.strVFirstMutableCopy address : 0x7f9882f990c0; a

        2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirst address : 0x7f9882f99080; c

        2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVSecond address : 0x7f9882f99080; c

        2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirstCopy address : 0xa000000000000611; a

        2016-04-28 13:46:33.506 copyTest[4299:93432] 6.strVFirstMutableCopy address : 0x7f9882f990c0; a

        2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirst address : 0x7f9882f99080; c

        2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVSecond address : 0x7f9882f99080; c

        2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirstCopy address : 0xa000000000000611; a

        2016-04-28 13:46:33.506 copyTest[4299:93432] 7.strVFirstMutableCopy address : 0x7f9882f990c0; c

   对于非容器类变量的拷贝可以做个总结:对不可变对象使用copy,相当于引用计数加1,不会分配新的内存;对不可变对象使用mutableCopy,会分配新的内存地址,新旧对象的改变不会互相影响;对可变对象使用copy或mutableCopy,都会分配新的内存,新旧对象的改变不相互影响。

 

转载于:https://www.cnblogs.com/zhizi-material/p/5442837.html

你可能感兴趣的文章
C#中构造函数的作用
查看>>
添加service到SystemService硬件服务
查看>>
The Model Complexity Myth
查看>>
解决:对 PInvoke 函数的调用导致堆栈不对称问题
查看>>
HTML5学习笔记简明版(10):过时的元素和属性
查看>>
Codeforces Round #313 (Div. 1) B. Equivalent Strings
查看>>
iOS开发-UITextField手机号和邮箱验证
查看>>
使用mvn生成webapp失败,尚未找到原因
查看>>
吐槽C++:C++ 类成员变量初始化 之 初始化带有参数的构造函数 的类成员变量。...
查看>>
跑Java -jar somefile.jar时会发生什么(一个)
查看>>
iOS开发网络篇—GET请求和POST请求
查看>>
UVA 10139 Factovisors(数论)
查看>>
Codeforces 458A Golden System
查看>>
java通过抛异常来返回提示信息
查看>>
LPC43xx双核笔记
查看>>
Flex4将对象转换成json串
查看>>
实现jquery.ajax及原生的XMLHttpRequest调用WCF服务的方法
查看>>
Swift - 多行文本输入框(UITextView)的用法
查看>>
hdu 1251 统计拼图
查看>>
Java多线程6:synchronized锁定类方法、volatile关键字及其他
查看>>