深浅复制

读前小提示:对于深浅复制有一个清楚的了解,对于学习oc的朋友来说,至关重要。那么首先,我们要明白深浅复制是如何定义的呢。这里为了便于朋友们理解,定义如下。

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

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

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

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

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

暂时不做讲解。

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

4、一般来讲,

浅层复制:复制引用对象的指针。

深层复制:复制引用对象内容。

这种定义在多层复制的时候,就显得模糊。所以本文定义与它并不矛盾。

反而是对它的进一步理解和说明。

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

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

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

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

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

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

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

 最近有一个好朋友问我,什么时候用到深浅复制呢?那么我就把我所总结的一些分享给大家,希望能帮助你们更好的理解深浅复制!

那么先让我们来看一看下边数组类型的转换

1、不可变对象→可变对象的转换:

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

NSMutableArray  *str2=[array1 mutableCopy];

2、可变对象→不可变对象的转换:

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

NSArray *array1=[  array2    Copy];

3、可变对象→可变对象的转换(不同指针变量指向不同的内存地址)

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

NSMutableArray  *str2=[array1 mutableCopy];

通过上边的两个例子,我们可轻松的将一个对象在可变和不可变之间转换,并且这里不用考虑内存使用原则(即引用计数的问题)。没错,这就是深拷贝的魅力了。

4、同类型对象之间的指针复制(不同指针变量指向同一块内存地址):

a、

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

NSMutableString *str2=[str1   retain];

   [str1  release];

b、

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

NSArray  *str2=[array1 Copy];

[array1 release];

 通俗的讲,多个指针同时指向同一块内存区域,那么这些个指针同时拥有对该内存区的所有权。所有权的瓜分过程,这时候就要用到浅拷贝了。

则简化为:

问:什么时候用到深浅拷贝?

答:深拷贝是在要将一个对象从可变(不可变)转为不可变(可变)或者将一个对象内容克隆一份时用到;

     浅拷贝是在要复制一个对象的指针时用到。

时间: 2024-08-09 08:33:08

深浅复制的相关文章

详谈OC(object-c)深浅复制/拷贝-什么情况下用retain和copy

读前小提示:对于深浅复制有一个清楚的了解,对于学习oc的朋友来说,至关重要.那么首先,我们要明白深浅复制是如何定义的呢.这里为了便于朋友们理解,定义如下. 浅 复 制:在复制操作时,对于被复制的对象的每一层复制都是指针复制. 深 复 制:在复制操作时,对于被复制的对象至少有一层复制是对象复制. 完全复制:在复制操作时,对于被复制的对象的每一层复制都是对象复制. 注:1.在复制操作时,对于对象有n层是对象复制,我们可称作n级深复制,此处n应大于等于1. 2.对于完全复制如何实现(目前通用的办法是:

OC-深浅复制

[OC学习-26]对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝 对象的拷贝分为浅拷贝和深拷贝, 浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址. 深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性,即完全是两个东西,只不过内容相同而已. 拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:<NSCopying>和<NSMutableCopying>相当于一个是拷贝,另一个是拷贝后可修改. (1

python 深浅复制与指针内存

Python是一门很好的语言,他的优点在于拥有巨大灵活性的同时也拥有无比的严谨性,其他语言规定了很多语法,告诉你什么情况下,语法就是这样的,而Python却用很少的规定,延伸出很多语法,有些语法看上去很奇怪,仔细分析却是那么的合理.今天思考了Python中关于指针和深浅复制的问题,下面希望能通过根据内存空间的变化对这些让人头疼的问题作出一个解释. 首先看第一个例子: a = 1 b = a b = 2 print 'a = %s' %a, 'b = %s'%b 结果:a = 1 b = 2 当执

Python基础(五):列表的深浅复制

首先我们需要明确列表的深浅复制是针对被嵌套的列表而言的,也就是说只有对嵌套列表我们才需要考虑这个问题.来看例子. list1=['老大','老二',['老三','老四','老五'],'老六','老七'] list2=list1.copy() print(list1,'\n',list2) #打印两个列表 print(id(list1),'\n',id(list2)) #打印两个列表的地址 print(id(list1[2]),'\n',id(list2[2])) #打印两个嵌套列表的地址 运行结

5——深浅复制、bytes和bytearray、linux用户

深浅复制 深浅复制只有在列表嵌套列表的情况下讨论 如果想保留修改之前的数据,就可以使用列表的复制,但要注意列表嵌套情况下的问题 l1 = [1,[2, 3]] l2 = l1.copy() #copy 浅复制 随着l1或l2的改变而发生改变 #浅复制只能改变第一层列表的数据,不能改变列表中嵌套的数据 ? import copy l3 = copy.deepcopy(l1) #深复制 能改变列表中所有嵌套的数据  bytes二进制序列类型 01 指定长度的零填充字节对象: [in] bytes(3

Python格式化输出和深浅复制

字符串的四种拼接方法,常用格式化 deepcopy(深复制) bytes 和 bytearray 的基本用法 字符串拼接 使用 + 格式化字符串 使用join 用单引号内的字符来拼接,参数填一个整体 使用format ,占位符:{} 字符串格式化输出 % 规定了对应位置的值只能填对应的类型 %s    %字符串 %d    %数字(十进制) %f    %浮点数 %s 与 %r 的区别,一个输出带引号,一个输出不带引号 其它了解即可 %c    %ASCII字符 %o    转换成8进制 %x 

深浅复制的的理解与区别

1.浅复制,仅仅是复制对象本身,并没有对所含的的对象进行复制,仅仅是对所含的对象进行Retain一下,引用计数加1 2.深复制,不仅仅对对对象本身进行复制,还对所含的对象进行复制,拷贝出一个副本. NSMutableArray *array = [NSMutableArray arrayWithCapacity:2]; for (int i=0; i<2; i++) { [array addObject:(以一个类为对象)类名 P]; } [array copy];//则类对象不会被复制,仅仅是

原型模式中的深浅复制

用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象,这就是原型模式.在.net框架中有个ICloneable接口,里面就有个Clone()的方法:我们在实际的开发过程中只需要实现这个接口并重新写Clone()方法就可以了.我们先看看结构图: 原型模式说白了就是复制一个更实例对象一样的对象:屏蔽了复制的细节问题.我们在实际的项目开发过程中会遇到深复制和浅复制两种.如果我们的对象实例中还有对象,则我们需要用深复制的方式才能复制成功:要不然我们对象实例中的对象修改了,所有的地方都会被修改掉.

C++中的深浅复制_实践示例

类定义中,如果未提供自己的拷贝构造函数,则C++提供一个默认拷贝构造函数,就像没有提供构造函数时, C++提供默认构造函数一样. C++提供的默认拷贝构造函数工作的方法是:完成一个成员一个成员的拷贝,如果成员是类对象,则调用 其拷贝构造函数或者默认拷贝构造函数. /*-------------------------------------- 在默认拷贝构造函数中,拷贝的策略是逐个成员依次拷贝,但是,一个类可能会拥有资源,如果拷贝构造函数 简单地制作了一个该资源的拷贝,而不对它本身分配,就得面临