OC-深浅复制

【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝

拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:<NSCopying>和<NSMutableCopying>相当于一个是拷贝,另一个是拷贝后可修改。

 

(1)浅拷贝的案例。有一个Person类,它创建一个person1对象后,用person1再拷贝一个person2出来。

//Person类的Person.h文件
#import <Foundation/Foundation.h>
//因为这个类要支持拷贝,所以需要引入拷贝协议,有两种,后一种拷贝后可修改
@interface Person : NSObject<NSCopying,NSMutableCopying>
@property(nonatomic,copy) NSString* name; @property(nonatomic,retain) NSNumber* age; @end
//这是Person.m文件
#import "Person.h"
@implementation Person
//这是系统函数,可以直接拷贝过来 - (id)copyWithZone:(NSZone *)zone{  Person *person=[[[self class]allocWithZone:zone]init]; //默认格式  person.name=_name; //浅拷贝就是直接赋值即可  person.age=_age; //浅拷贝就是直接赋值即可  return person; } @end
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"//记得引入头文件
int main(int argc, const char * argv[])
{
 @autoreleasepool {   Person *person1=[[Person alloc]init];   person1.name=@"jack";   person1.age=@18;   Person *person2=[person1 copy];   NSLog(@"%p,%p",person1,person2);//输入两个对象地址,不同   NSLog(@"%p,%p",person1.age,person2.age);//输出两个对象的属性地址,相同  }  return 0; }

结果:

0x1002036f0,0x100200330 //不同
0x1227,0x1227 //相同

(2)深拷贝的案例。

按道理是只需要把Person.m里面的赋值语句改成下面的样子,就能实现深拷贝:

person.name=[_name copy]; 
person.age=[_age copy];

但是,因为cocoa优化过了,所以有如下规则:

a:如果是Foundation框架里的不可变对象,就是Array,NSString等创建的对象,直接用copy来拷贝相当于retain,也就是属性还是同一个;

b:如果是用mutableCopy来拷贝,不管是可变还是不可变对象,属性神马的都直接拷贝了一份,即真正意义上得拷贝,它拷贝出来的对象统统都是可变的;

c:如果是可变对象,我们用copy也能实现真正意义上的拷贝,但是拷贝出来的对象是不可变的。

所以,我们拿name实验(因为age没有mutableCopy)实现语句的修改:

person.name=[_name mutableCopy]
person.age=[_age copy];

然后再输出person1和person2的name属性的地址,发现就不同了。

总结:

浅拷贝和深拷贝在实际项目中不常用,可以做一般了解。

 

 

 

OC-深浅复制

   浅 复 制:在复制操作时,对于被复制的对象的每一层复制都是指针复制。

   深 复 制:在复制操作时,对于被复制的对象至少有一层复制是对象复制。

   完全复制:在复制操作时,对于被复制的对象的每一层复制都是对象复制。

 

        注:1在复制操作时,对于对象有n层是对象复制,我们可称作n级深复制,此处n应大于等于1。

              2对于完全复制如何实现(目前通用的办法是:迭代法和归档),这里后续是否添加视情况而定,

              暂时不做讲解。

          3、指针复制俗称指针拷贝,对象复制也俗称内容拷贝。

 

retain:始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。

 

copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,

         引用计数每次加一。始终返回一个不可变对象。

 

mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象。

 

不可变对象:值发生改变,其内存首地址随之改变。

   可变对象:无论值是否改变,其内存首地址都不随之改变。

   引用计数:为了让使用者清楚的知道,该对象有多少个拥有者(即有多少个指针指向同一内存地址)。

 

亲爱的读者朋友,下面是我用于验证的详细代码。对于验证还能得出什么结论,我希望朋友们能自己多多发掘一下。这里只做以上几点总结。对于本文有任何疑问请与我联系,欢迎指出本文不足的地方,谢谢!

#import<Foundation/Foundation.h>

 

int main (int argc, const char * argv[])

{

 

    @autoreleasepool {

 

    //第一种:非容器类不可变对象

 

        NSString *str1=@"one day";

        

          printf("n初始化赋值引用计数为::::%lu",str1.retainCount);

        NSString *strCopy1=[str1 retain];

          printf("n继续retain引用计数为:::%lu",str1.retainCount);

        NSString *strCopy2=[str1 copy];

          printf("n继续copy后引用计数为::::%lu",str1.retainCount);

        NSString *strCopy3=[str1 mutableCopy];

                printf("n继续mutableCopy后为:::%lun",str1.retainCount);

        

        printf("n非容器类不可变对象n原始地址::::::::::%p",str1);

        printf("nretain复制::::::::%p",strCopy1);

        printf("ncopy复制::::::::::%p",strCopy2);

        printf("nmutableCopy复制:::%p",strCopy3);

 

    //这里说明该类型不存在引用计数的概念

 

  // 初始化赋值引用计数为:18446744073709551615

  // 继续retain引用计数为:18446744073709551615

  // 继续copy后引用计数为:18446744073709551615

  // 继续mutableCopy后为:18446744073709551615

   

   //非容器类不可变对象

   //原始地址::::::::::0x1000033d0

   //retain复制::::::::0x1000033d0//浅复制

   //copy复制::::::::::0x1000033d0//浅复制

   //mutableCopy复制:::0x10010c420//深复制

  

 

      printf("n");

 //第二种:容器类不可变数组

 

        NSArray *array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

        

          printf("n初始化赋值引用计数为::::::::::::%lu",array1.retainCount);

        NSArray *arrayCopy1 = [array1 retain];

          printf("n继续retain后引用计数为:::::::::%lu",array1.retainCount);

        NSArray *arrayCopy2 = [array1 copy];

          printf("n继续copy后引用计数为:::::::::::%lu",array1.retainCount);

        NSArray *arrayCopy3 = [array1 mutableCopy];

          printf("n继续mutableCopy后引用计数为::::%lun",array1.retainCount);

        

    printf("n容器类不可变数组n原始地址::::::::::%ptt%p",array1,[array1 objectAtIndex:1]);

        printf("nretain复制::::::::%pt%p",arrayCopy1,[arrayCopy1 objectAtIndex:1]);

        printf("ncopy复制::::::::::%pt%p",arrayCopy2,[arrayCopy2 objectAtIndex:1]);

        printf("nmutableCopy复制:::%pt%p",arrayCopy3,[arrayCopy3 objectAtIndex:1]);

        

   

    //初始化赋值引用计数为::::::::::::1

    //继续retain后引用计数为:::::::::2

    //继续copy后引用计数为:::::::::::3

    //继续mutableCopy后引用计数为::::3

 

    //容器类不可变数组

    //原始地址::::::::::0x10010c6b0 0x100003410

    //retain复制::::::::0x10010c6b0 0x100003410//浅复制

    //copy复制::::::::::0x10010c6b0 0x100003410//浅复制

    //mutableCopy复制:::0x10010c760 0x100003410//深复制

 

    

        printf("n");

 //第三种:非容器类可变对象

 

        NSMutableString *str2=[NSMutableString stringWithString:@"two day"];

        

          printf("n初始化赋值引用计数为::::::::::::%lu",str2.retainCount);

        NSMutableString *strCpy1=[str2 retain];

          printf("n继续retain后引用计数为:::::::::%lu",str2.retainCount);

        NSMutableString *strCpy2=[str2 copy];

          printf("n继续copy后引用计数为:::::::::::%lu",str2.retainCount);

        NSMutableString *strCpy3=[str2 mutableCopy];

                printf("n继续mutableCopy后引用计数为::::%lun",str2.retainCount);

        

        printf("n非容器类可变对象n原始地址::::::::::%p",str2);

        printf("nretin复制::::::::%p",strCpy1);

        printf("ncopy复制::::::::::%p",strCpy2);

        printf("nmutableCopy复制:::%p",strCpy3);

       

 

 

         //初始化赋值引用计数为::::::::::::1

         //继续retain后引用计数为:::::::::2

         //继续copy后引用计数为:::::::::::2

         //继续mutableCopy后引用计数为::::2

 

         //非容器类可变对象

         //原始地址::::::::::0x10010c560

         //retain复制::::::::0x10010c560//浅复制

         //copy复制::::::::::0x100102720//深复制

       //mutableCopy复制:::0x10010c880//深复制

         

        printf("n");

 //第四种:容器类可变数组

 

  NSMutableArray *array2   = [NSMutableArrayarrayWithObjects:@"aa",@"bb",@"cc",@"dd",nil];

        

         printf("n初始化赋值引用计数为::::::::::%lu",array2.retainCount);

       NSMutableArray *arrayCpy1 = [array2 retain];

         printf("n继续retain后引用计数为:::::::%lu",array2.retainCount);

       NSMutableArray *arrayCpy2=[array2 copy];

         printf("n继续copy后引用计数为:::::::::%lu",array2.retainCount);

       NSMutableArray *arrayCpy3 = [array2 mutableCopy];

         printf("n继续mutableCopy后引用计数为::%lun",array2.retainCount);

        

       printf("n容器类可变数组n原始地址:::::::::::%pt%p",array2,[array2 objectAtIndex:1]);

       printf("nretain复制:::::::::%pt%p",arrayCpy1,[arrayCpy1 objectAtIndex:1]);

       printf("ncopy复制:::::::::::%pt%p",arrayCpy2,[arrayCpy2 objectAtIndex:1]);

       printf("nnmutableCopy复制:::%pt%p",arrayCpy3,[arrayCpy3 objectAtIndex:1]);

       

        

         //初始化赋值引用计数为::::::::::1

         //继续retain后引用计数为:::::::2

         //继续copy后引用计数为:::::::::2

         //继续mutableCopy后引用计数为::2

 

         //容器类可变数组

         //原始地址:::::::::::0x10010e6c0 0x1000034b0

         //retain复制:::::::::0x10010e6c0 0x1000034b0//浅复制

         //copy复制:::::::::::0x10010e790 0x1000034b0//深复制

         //nmutableCopy复制:::0x10010e7c0 0x1000034b0//深复制

         

        

 

    }

    return 0;

}

 

转载于:https://www.cnblogs.com/iOS-mt/p/4121583.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376464.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机科学导论(第一次阅读)

时间&#xff1a; 2017年4月22日----2017年4月26 这是一本计算机入门书籍&#xff0c;粗略地描述了计算机各个方面的内容。当然对于一些十分复杂的知识&#xff0c;也仅仅是大概描述了这方面知识的一些了解知识。

配置SQLServer,允许远程连接

需要别人远程你的数据库&#xff0c;首先需要的是在一个局域网内&#xff0c;或者连接的是同一个路由器&#xff0c;接下来就是具体步骤&#xff1a; &#xff08;一&#xff09;首先是要检查SQLServer数据库服务器中是否允许远程链接。其具体操作为&#xff1a; &#xff08;1…

弹出打开/保存文件对话框 选择文件夹对话框

打开/保存文件对话框: CFileDialog::CFileDialog(BOOL bOpenFileDialog, //为TRUE则显示打开对话框&#xff0c;为FALSE则显示保存对话文件对话框LPCTSTR lpszDefExt NULL, //默认的文件扩展名LPCTSTR lpszFileName NULL, //默认的文件名DWORD dwFlags OFN_HIDEREADONLY | O…

SharePoint 2013的100个新功能之网站管理(一)

一&#xff1a;设置盘 网站操作现在被替换为新的&#xff08;设置&#xff09;盘子。一些新的操作像添加一个应用、添加一个页面或设计管理器被添加而像创建网站则从菜单中移除了。 二&#xff1a;移除以其他用户身份登录 在SharePoint 2013中&#xff0c;从用户欢迎菜单中移除…

160 - 13 badboy

偷懒了很久也是时候要继续开始学习了。 环境&#xff1a; windows xp sp3 工具&#xff1a; VB Decompiler v8.3 这次是个vb文件&#xff0c;所以尝试一下用这个的感觉。 打开文件之后发现有两个CrackMe选择&#xff0c;分别是1.0版本和2.0版本。 打开vb decompiler&#…

VBS操作剪切板

VBS操作剪切板 设置剪切板的内容 Dim Form, TextBox Set Form CreateObject("Forms.Form.1") Set TextBox Form.Controls.Add("Forms.TextBox.1").Object TextBox.MultiLine True TextBox.Text "忘记了&#xff0c;喜欢一个人的感觉" TextBo…

MVN生成java项目

mvn archetype:create -DgroupIdcom.mycompany.app -DartifactIdmyWeb -DarchetypeArtifactIdmaven-archetype-webapp 转载于:https://www.cnblogs.com/alaricblog/p/3278239.html

160 - 14 bjanes.1

环境&#xff1a; window xp sp3 工具&#xff1a; ollydbg &#xff0c;exeinfo pe 拿到程序后&#xff0c;查壳。显示是无壳的VB程序 用之前用的VB decompiler载入&#xff0c;没找到有用的东西&#xff0c;还是用回了OD。 OD载入&#xff0c;运行起来。输入“GNUBD”然后点…

小结C++中一些自带的好用东西

STL部分 <set>/<multiset> 支持插入一个元素&#xff0c;删除指定key值的元素&#xff0c;查找指定key值的元素&#xff0c;返回最大/小值&#xff0c;找前驱&#xff0c;找后继&#xff0c;返回指定key值的相同元素个数。 部分代替平衡树中一些操作。不能updata或…

160 - 15 blaster99.exe

环境&#xff1a; windows xp sp 3 工具&#xff1a; Ollydbg 和 exeinfo pe 查壳&#xff0c;还是无壳的vb程序。 打开&#xff0c;有一个nag窗口&#xff0c;点击”确认”的话才会弹出输入serial的窗口&#xff0c;点“取消”的话会关闭程序 OD载入&#xff0c;运行到弹出n…

Freemarker宏和函数的用法和区别

1.宏&#xff08;macro&#xff09;写法&#xff1a;<#macro page url page maskSize5> <#if (number pages)><li><a href"javascript:void(0);">下一页</a></li><li><a href"javascript:void(0);">尾…

聚类算法初探(八)数据尺度化问题

文中尺度化的一些具体公式可参见 http://blog.csdn.net/itplus/article/details/10088101 其他相关链接 引言 预备知识 直接聚类法 K-means DBSCAN OPTICS 聚类分析的效果评测 作者: peghoty 出处: http://blog.csdn.net/itplus/article/details/10484553 欢迎转载/分享, 但请…

160 - 16 bjanes.2

环境&#xff1a; windows xp sp3 工具&#xff1a; bjanes.2&#xff0c;HashCalc 这个和14题是一样的&#xff0c;看名字就发现都是2.0A&#xff0c;然后用HashCalc来计算一下MD5&#xff0c;发现它们的值是相同的。 如果没猜错&#xff0c;应该就是在14题是被放错题了。

HDU 1269

很水的TARJAN求强联通图的问题。 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace std; const int N10010; const int M100010; int head[N],dfn[N],low[N],stack[N],st; struct Edge{int u,v;int nxt…

maven库文件所在目录

C:\Documents and Settings\jgzhang2\.m2\repository转载于:https://www.cnblogs.com/yipihema/p/3289140.html

imul和mul的计算

imul是把操作数符号也算上的&#xff1a; 设 AL 0B4H BL 11H 执行 imul BL 后&#xff1a;AL 0FAF4 原因&#xff1a; imul是把符号也算上的&#xff0c;所以AL是某个数的补码&#xff0c;故得AL -4C -76D&#xff0c;而BL 17D 是正数&#xff0c;相乘得-1292&#x…

【待完善】make: command not found,以及libtool.m4 and ltmain.sh have a version mismatch问题的解决方案...

之前为了使用一个库&#xff0c;都是去下载源码&#xff0c;然后根据开发者提供的README手动用GCC编译&#xff0c;一直不能使用Makefile感觉很蛋痛&#xff0c;比如最近使用的ZThread 还是怪自己以前过于依赖IDE 最近发现用Cygwin就可以使用诸如./configure, make这样的命令&a…

ubuntu 12.04 下安装 MySQL 5.5

参考&#xff1a;http://www.linuxidc.com/Linux/2011-12/48920.htm《Ubuntu 11.04 通过 apt 安装 MySQL 5.1 的全过程记录》 说明&#xff1a;在mysql官网下载ubuntu下的安装包进行安装&#xff0c;不是一件容易的事。这里不是指下载&#xff0c;而是指安装配置过程。 所以可以…

160 - 17 bjanes.3

环境&#xff1a; Wiondws XP sp3 工具&#xff1a; ollydbg&#xff0c;ExeInfo PE 查壳&#xff1a; 用Exeinfo PE 查壳&#xff0c;没有壳&#xff0c;是VB写的 过程&#xff1a; 一&#xff1a;随便输入一个serial&#xff0c;得到一个错误信息消息框&#xff0c;OD载入…

菜鸟nginx源码剖析

菜鸟nginx源码剖析 配置与部署篇&#xff08;一&#xff09; 手把手配置nginx “I love you” TCMalloc 对MYSQL 性能 优化的分析 菜鸟nginx源码剖析系列文章解读 Author&#xff1a;Echo Chen&#xff08;陈斌&#xff09; Email&#xff1a;chenb19870707gmail.com Blog&…