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协议,重写对应的方法,才可使用,要不然会直接崩溃的噢。

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

相关文章推荐

copy,mutableCopy 理解

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

copy和mutableCopy都是浅拷贝!!!

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

Objective-C常用数据类型之间的转换

OC 常用数据类型之间的转换 1: NSString   NSInteger     NSInteger转化 NSString类型:       [ NSString  stri...

黑马程序员——为什么 Objective-C 很难——黑马 ios 技术博客

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------- 语法: 首先我们谈谈神马叫做编程语言,编程语言是一种让人们能读懂并且能够展现...

objective-c copy mutableCopy 拷贝对象

原来不是所有的对象都支持 copy 只有遵守NSCopying 协议的类才可以发送copy消息 只有遵守NSMutableCopying 协议的类才可以发送mutableCopy消息 假如发...

全面了解Objective-C:Copy

copy 老生常谈了。估计是个iOS开发者都知道这事。这篇文章就稍微全面写一写。 原文章 传送门1、系统对象的copy与mutableCopyNSObject类提供了copy和mutableCopy方...
  • WiKi_Su
  • WiKi_Su
  • 2017年08月08日 12:07
  • 142

Objective-C ---- retain/copy/assign/等语义修饰理解

【atomic/nonatomic】 (1)atomic[默认属性]:OC使用的一种线程保护技术,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhon...

Objective-c中copy,retain,assign,readonly,read write,nonatomic的区别

nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问。 (atomic是Objc使用的一种线程保护技术,基本...
  • yqmfly
  • yqmfly
  • 2012年06月18日 14:57
  • 801

Objective-C中的@property和@synthesize用法及参数(readwrite/readonly)(assign/retain/copy)(atomicity/nonatomic)

用@property,@synthesize来代替get,set方法,用起来很简单,可以省掉很多的代码量,当需要用SET,GET方法的地方,我们可以用@property,@synthesize来简单的...

Objective-C中为何用copy修饰block

简单来说,block就像一个函数指针,指向我们要使用的函数。 就和函数调用一样的,不管你在哪里写了这个block,只要你把它放在了内存中(通过调用存在这个block的方 法或者是函数),不管放在栈...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Objective-C中Copy和MutableCopy,你了解多少?
举报原因:
原因补充:

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