Objective-C中Copy和MutableCopy,你了解多少?

原创 2015年07月09日 15:23:11

在iOS开发中,对于copy和mutableCopy都不陌生。如果您不知道它们之间区别的话,看完本文我相信您肯定会分的很清楚。接下来,就通过几个小例子来了解一下吧。

NO.1

NSArray * array = [[NSArray alloc] initWithObjects:@"sogouqa", nil];

NSArray * retainArray = array;

NSArray * copyArray = [array copy];

NSArray * mutableCopyArray = [array mutableCopy];

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(array), &array, array);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(retainArray), &retainArray, retainArray);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(copyArray), ©Array, copyArray);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(mutableCopyArray), &mutableCopyArray, mutableCopyArray);


这个是在ARC下很简单的小例子,首先初始化一个数组array,然后做了下赋值操作,接着做了copy和mutableCopy操作。后面的就是打印一些信息,_objc_rootRetainCount()函数是在ARC下打印对象的retainCount。后面两个信息也就是指针的地址和指针指向的对象的地址。通过retainCount和指针指向的地址,可以判断出来那些对象指的是同一块地址。结果如下:

3 0x7fff5fbff7a8 0x100306960

3 0x7fff5fbff7a0 0x100306960

3 0x7fff5fbff798 0x100306960

1 0x7fff5fbff790 0x100306a00


接下来我们来分析下结果,首先执行完以上操作以后,array、retainArray、copyArray的retainCount都是3,而且他们指向的地址都是0x100306960。这也就是说明他们指向的是同一块内存地址。所以NSArray调用copy函数,是浅拷贝,copyArray指针和array指针本身不是同一个地址,但是他们指向的空间是相同的。对于上面这个例子来说,NSArray调用直接赋值,和调用copy进行赋值,结果是完全一致的,都是浅拷贝。而mutableCopy,很明显是深拷贝,因为mutableCopyArray和array指向的地址不一样。针对上面的例子,我们可以得出:

NSArray的copy函数是浅拷贝,mutableCopy函数是深拷贝。

接下来我们继续做实验,把上面例子所有的NSArray,都替换成NSMutableArray,调用的函数全不变,那么结果会是什么样子?

NO.2

NSMutableArray * array = [[NSMutableArray alloc] initWithObjects:@"sogouqa", nil];

NSMutableArray * retainArray = array;

NSMutableArray * copyArray = [array copy];

NSMutableArray * mutableCopyArray = [array mutableCopy];

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(array), &array, array);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(retainArray), &retainArray, retainArray);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(copyArray), ©Array, copyArray);

NSLog(@"%d\t%p\t%p", _objc_rootRetainCount(mutableCopyArray), &mutableCopyArray, mutableCopyArray);


这次输入应该是什么样子的:

2 0x7fff5fbff7a8 0x1002069d0

2 0x7fff5fbff7a0 0x1002069d0

1 0x7fff5fbff798 0x1002074f0

1 0x7fff5fbff790 0x100207510

从结果上看,跟之前的结构略有不同,普通赋值retainArray和array指向的是同一块内存地址,retainCount为2,显然是浅拷贝。但是调用copy和mutableCopy函数,指针指向的地址不同,那说明:

NSMutableArray调用copy和mutableCopy都是深拷贝。

但是调用copy和mutableCopy有什么区别呢?别着急,我们接着往下看。接着上一个例子,我们来打印一下各个对象的类型:

NO.3

NSMutableArray * array = [[NSMutableArray alloc] initWithObjects:@"sogouqa", nil];

NSMutableArray * copyArray = [array copy];

NSMutableArray * mutableCopyArray = [array mutableCopy];

NSLog(@"array class = %@", [array className]);

NSLog(@"copyArray Class = %@", [copyArray className]);

NSLog(@"mutableCopyArray = %@", [mutableCopyArray className]);

结果:

array class = __NSArrayM

copyArray Class = __NSArrayI

mutableCopyArray = __NSArrayM

我们可以看到copyArray是_NSArrayI,说明是Immutable Array,也就是普通的NSArray类型,mutableCopyArray是_NSArrayM,也就是NSMutableArray类型。那么接下来我们看下NSArray调用copy和mutableCopy都生成什么类型的对象。

NO.4

NSArray * array = [[NSArray alloc] initWithObjects:@"sogouqa", nil];

NSArray * copyArray = [array copy];

NSArray * mutableCopyArray = [array mutableCopy];

NSLog(@"array class = %@", [array className]);

NSLog(@"copyArray Class = %@", [copyArray className]);

NSLog(@"mutableCopyArray = %@", [mutableCopyArray className]);

结果:

array class = __NSArrayI

copyArray Class = __NSArrayI

mutableCopyArray = __NSArrayM

结果显示,NSArray调用copy生成的是NSArray对象,调用mutableCopy生成的是NSMutableArray对象。

总结

1. NSArray调用copy,是浅拷贝,生成的是NSArray对象;

2. NSArray调用mutableCopy,是深拷贝,生成的是NSMutableArray对象;

3. NSMutableArray调用copy,是深拷贝,生成的是NSArray对象;

4. NSMutableArray调用mutableCopy,是深拷贝,生成的是NSMutableArray对象。


PS:这个理论也适用于Foundation框架里面的其他对象,例如string,dictionary等。如果自定义的类需要使用copy或mutableCopy函数的话,就要事先实现好NSCopying或NSMutableCopying协议,重写对应的方法,才可使用,要不然会直接崩溃的噢。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Objective-C中Copy和MutableCopy,你了解多少?

在iOS开发中,对于copy和mutableCopy都不陌生。如果您不知道它们之间区别的话,看完本文我相信您肯定会分的很清楚。接下来,就通过几个小例子来了解一下吧。 NO.1 NS...
  • sogouauto
  • sogouauto
  • 2015年07月09日 15:23
  • 531

浅拷贝&深拷贝|| MutableCopy& Copy

浅拷贝(Shallow Copy)与深拷贝(Deep Copy) 在Objective-C中并不是所有的对象都支持Copy,MutableCopy,遵守NSCopying协议的类才可以发送Copy...
  • sinat_34194127
  • sinat_34194127
  • 2016年07月26日 21:19
  • 233

关于NSString的copy和mutableCopy

简单的说就是有没有为对象申请一块新的内存空间,也可以说有没有一个新的地址。对于深复制,指针存储的地址和被拷贝的指针存储的地址不同。 首先说一下关于NSString的copy和mutableCop...
  • small_smart_jin
  • small_smart_jin
  • 2016年03月04日 18:01
  • 452

copy和mutableCopy都是浅拷贝!!!

嗯,标题就是要这么醒目,不然没人看。虽然要追求醒目,但绝不是信口开河。所有系统容器类的copy或mutableCopy方法,都是浅拷贝!!! 是的,你没有听错。 所有系统容器类的copy或muta...
  • qq_18425655
  • qq_18425655
  • 2016年05月05日 20:16
  • 2096

copy,mutableCopy 理解

copy,mutableCopy 理解 好记性不如烂笔头,好理解不如写出来,前一句非常正确,后一句是我加的,嘿嘿。 突击学习了下2者的却别,记录如下。 OC中可变对象和不可对象经常用的如下: NSSt...
  • fg313071405
  • fg313071405
  • 2013年11月21日 12:02
  • 7475

iOS-copy与mutableCopy浅析

在iOS开发中,当提到深拷贝和浅拷贝的时候,大家都说懂,简单;都会说,浅拷贝:指针(地址)拷贝,不会产生新对象;深拷贝:内容拷贝,会产生新对象 但当问及大家copy与mutableCopy的时候,他...
  • Mazy_ma
  • Mazy_ma
  • 2016年07月13日 16:40
  • 2871

属性修饰copy;copy、mutableCopy;NSCopying NSMutableCopying

深拷贝和浅拷贝的区别是,深拷贝是开辟新的内存,创建一个新的对象,即深拷贝产生的对象,与被拷贝的对象没有必然联系。 浅拷贝是拷贝当前对象的地址,即拷贝出来的对象的指针和被拷贝的对象的指针相同,当一个对...
  • yan_1564335
  • yan_1564335
  • 2016年08月22日 10:08
  • 172

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

请尊重原作者的辛苦劳动,转载请注明出处。 实践是检验真理的唯一标准。下面就让我们在实践中认识copy和mutableCopy的共同点和区别。 1.copy和mutableCopy的实现过程。 想要一个...
  • joe1209
  • joe1209
  • 2014年08月14日 19:57
  • 1549

iOS Copy 和 MutableCopy的区别 深浅拷贝的区别

原创的链接在这里: 原创的地址请点击这里哦 概述 对于系统的非容器类对象,对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。如果是对可变对象复...
  • fanjunxi1990
  • fanjunxi1990
  • 2013年11月20日 17:27
  • 5378

iOS中copy和mutableCopy的详细分析

copy和mutableCopy在实际开发中常用到,同时,copy属性修饰符也是我们在定义NSString、NSArray和block等需要用到的,要较好地掌握它们,需要从原理上去分析于理解,本文侧重...
  • nineteen_
  • nineteen_
  • 2015年09月17日 21:24
  • 1936
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Objective-C中Copy和MutableCopy,你了解多少?
举报原因:
原因补充:

(最多只允许输入30个字)