copy和mutableCopy到底是浅拷贝还是深拷贝?

请尊重原作者的辛苦劳动,转载请注明出处。http://blog.csdn.net/jslsblog/article/details/38563009

实践是检验真理的唯一标准。下面就让我们在实践中认识copy和mutableCopy的共同点和区别。

1.copy和mutableCopy的实现过程。

想要一个对象能实现copy首先要继承NSCopying的协议,然后实现+ (id)copyWithZone:(struct _NSZone *)zone,mutableCopy对应的是NSMutableCopying协议和+ (id)mutableCopyWithZone:(struct _NSZone *)zone方法。

不同的对象,在实现copyWithZone:和mutableCopyWithZone:的时候实现方式是不同的,这就导致了不同的对象在调用了copy或者mutableCopy后有的是返回原来的指针,有的是返回一个新的指针。

2.NSString copy举例

eg1:常量

NSString *str1 = @"eg";

NSString *str2 = [str1 copy];

这时候打印retainCount,结果str1和str2的都是-1,说明对于字符串常量没有进行计数,copy的时候没有任何效果,结果等同于NSString *str2 = str1;

同理:NSString *str1 = [[NSString alloc] initWithString:@"12345"];

str1的retainCount = -1;说明这样创建也是常量,alloc没有分配内存。

eg2:不可变变量

NSString *str1 = [NSString stringWithFormat:@"eg"];

NSLog(@"str1 retainCount:%d",(int)[str1 retainCount]);

NSString *str2 = [str1 copy];

NSLog(@"str1 retainCount:%d",(int)[str1 retainCount]);

NSLog(@"str2 retainCount:%d",(int)[str2 retainCount]);

打印的结果是

str1 retainCount:1

str1 retainCount:2

str2 retainCount:2

而且你如果打印str1和str2的地址,你会发现两者的地址也是不同的,并且地址相差的长度为8.当[str1 release]的时候str1和str2的retainCount都变为1.从以上结果可以推测str1和str2指向同一个对象,享有相同的计数值。这时候的copy = retain。

eg3:可变变量

NSMutableString *str1 = [NSMutableString stringWithFormat:@"ss"];

NSLog(@"str1 retainCount:%d",(int)[str1 retainCount]);

NSString *str2 = [str1 mutableCopy];//或者使用 NSString *str2 = [str1 copy];

NSLog(@"str1 retainCount:%d",(int)[str1 retainCount]);

NSLog(@"str2 retainCount:%d",(int)[str2 retainCount]);

打印结果:

str1 retainCount:1

str1 retainCount:1

str2 retainCount:1

如果[str1 release];是不会影响str2的值和retainCount。从以上结果可以推断出copy 和mutableCopy等于从新创建一个新的NSString,并且把str1的值付给str2,str1和str2是完全不同的两个对象。

3.总结

从以上三个例子说明了不同的对象在不同的情况下对copyWithZone:和mutableCopyWithZone:的实现是不同的,不能一概而论。

浅拷贝就是复制一份指针,而深拷贝就是创建一个新的对象,然后把值复制过去,原来的对象和新建的对象之后没有任何关系。copy和mutableCopy不能一概的说是浅拷贝还是深拷贝,需要针对不同的实现方法来判断。

和NSString类似的类还有NSNumber. NSArray和 NSString略有不同。NSArray不论用什么方式创建都会retainCount=1,mutableCopy和copy都会创建新的数组。

copy和mutableCopy到底是浅拷贝还是深拷贝?

时间: 2024-08-01 10:43:22

copy和mutableCopy到底是浅拷贝还是深拷贝?的相关文章

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

最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/不可变对象: 4.Objective-C中的copy与mutableCopy方法. 一.指针与对象 在初始学习编程的时候,对于绝大多数面向对象编程的语言,这都是个绕不开的重点与难点.非常惭愧的是对它的认识我一直是不够的,并且感觉这项技术有许多的内容可以挖掘.说这是面向对象编程的核心思想也不为过.很多

Objective-c中对象的Copy、MutableCopy、浅拷贝、深拷贝

对象的复制就是复制一个对象作为副本,他会开辟一块新的内存(堆内存)来存储副本对象,就像复制文件一样,即源对象和副本对象是两块不同的内存区域.对象要具备复制功能,必须实现<NSCopying>协议或者<NSMutableCopying>协议,常用的可复制对象有:NSNumber.NSString.NSMutableString.NSArray.NSMutableArray.NSDictionary.NSMutableDictionary copy:产生对象的副本是不可变的 mutab

Python之美[从菜鸟到高手]--浅拷贝、深拷贝完全解读(copy源码分析)

可悲的我一直以为copy模块是用C写的,有时候需要深入了解deepcopy,文档描述的实在太简单,还是不知所云. 比如说最近看sqlmap源码中AttribDict的_deepcopy__有些疑惑, def __deepcopy__(self, memo): retVal = self.__class__() memo[id(self)] = retVal for attr in dir(self): if not attr.startswith('_'): value = getattr(se

Python(2.7.6) copy 浅拷贝与深拷贝

Python 标准库的 copy 模块提供了对象拷贝的功能. copy 模块中有两个函数 copy 和 deepcopy,分别支持浅拷贝与深拷贝. copy_demo.py import copy class MyClass(object): def __init__(self, name): super(MyClass, self).__init__() self.name = name a = [MyClass('huey')] b = copy.copy(a) c = copy.deepc

浅拷贝和深拷贝以及copy.copy

浅拷贝:"=" >>> a=[1,2,3]>>> b=a>>> a[1, 2, 3]>>> b[1, 2, 3]>>> id(a)91339472>>> id(b)91339472 所以:浅拷贝就是值相等,地址相同 深拷贝:"copy.deepcopy()" >>> import copy >>> c=copy.deepco

Objective-C Objective-C中的指针,及对象的直接指向,copy和mutablecopy

1.Objective-C的指针世界 OC一直是人感觉比较变态的一门语言,为什么呢?因为它的每个变量都是指针型,多的都几乎让人忘了那个*的存在了. 所以常常a=b这个等号让我产生错觉,总以为a从b那拷贝了一份. 然而这的的确确,却是个指针.a这个变量存的内容是b所在的地址. 比如我定义了一个Student的Class,new了stu1和stu2,并把stu2=stu1,那当两者任何一个进行修改时,两个变量的内容都会修改. Student *stu1=[[Student alloc]init];

iOS开发那些事儿(五)Objective-C浅拷贝与深拷贝

浅拷贝:copy操作出来的对象指针直接指向模板的地址.即两个对象公用一块内存地址 1 #import <Foundation/Foundation.h> 2 int main(int argc, const char * argv[]) { 3 @autoreleasepool { 4 NSString * testStr = @"connor"; 5 NSLog(@"testStr's Address = %p",testStr); 6 7 NSStr

Objective-C中的浅拷贝和深拷贝详解

  浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间.如: 1 2 char* str = (char*)malloc(100); char* str2 = str; 浅拷贝只是对对象的简单拷贝,让几个对象共用一片内存,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针. iOS 里面的浅拷贝: 在 iOS 里面, 使用retain 关键字进行引用计数,就是一种更加保险的浅拷贝.他既让几个指针共用同一片内存空间,又可以在release

Copy和MutableCopy

//    一: copy 与 retain 的区别 //    谁才有引用计数的概念: //    1. 堆区空间才有引用计数概念. //    2. 堆区的对象才会有引用计数. //%ld: - 1           %lu:18446744073709551615 //retain:始终是浅拷贝.引用计数每次加一. //返回对象是否可变与被复制的对象保持一致. //copy:对于可变对象为深拷贝,引用计数不改变; //对于不可变对象是浅拷贝,引用计数每次加一. //始终返回一个不可变对象