关于Copy的深度解析

其实也不算深度解析啦,主要是题目要响亮一点大家才有看的欲望嘛!!!

首先关于Copy想必在面试题中大家见过很多,下面我就写一下我对Copy的理解。

1.Copy是什么???

copy和mutableCopy是方法,是NSObject内定义的方法。

2.Copy有什么用???

copy顾名思义就是拷贝或者说克隆,所以copy的目的就是复制一份原来的内容,进一步思考为什么需要拷贝?显然:拷贝的目的就是改变原来的内容不影响副本,改变副本也不影响原来的内容。

3.从NSString,NSMutableString,NSArray,NSMutableArray说明深拷贝和浅拷贝的区别

首先大家来想一下为什么要用到Copy??Copy的目的所在是什么?为什么需要生成一个新的对象呢???

Copy是为了互不干扰,生成两个对象是为了相互改变的时候不影响另外一个对象。

其次大家要牢记一点,使用Copy方法得到的是不可变对象,使用mutableCopy方法得到的必须是可变对象

一.NSString、NSMutableString非容器对象分析

1.不可变字符串的copy和mutableCopy

NSString *str = @"xiaoming";

NSString *str1 = [str copy];

NSMutableString * str2 = [str mutableCopy];

NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",str,str,NSStringFromClass([str class]),str1,str1,NSStringFromClass([str1 class]),str2,str2,NSStringFromClass([str2 class]));

打印结果如下:

----str:0x10c8e4068,xiaoming,__NSCFConstantString----str1:0x10c8e4068,xiaoming,__NSCFConstantString----str2:0x608000266ac0,xiaoming,__NSCFString

通过上面的打印结果大家可以看到不可变的字符串经过copy之后没有生成对象,得到的是不可变字符串,经过mutableCopy之后生成了新的对象,得到是可变字符串。

为什么copy没有得到对象呢???因为原来的对象是不可以修改的,新拷贝的对象也是不可修改的,所以不会影响到另外一个对象。已经符合拷贝的目的 了,所以,OC为了对内存进行优化, 就不会生成一个新的对象。

为什么mutableCopy会生成新的对象呢?生成的是一个可变对象,这样两个对象其中一个对象改变而不影响另外一个对象。

2.可变字符串的copy和mutableCopy

NSMutableString *mulStr = [NSMutableString stringWithFormat:@"abc"];

NSString *mulStr1 = [mulStr copy];

NSMutableString * mulStr2 = [mulStr mutableCopy];

NSLog(@"----str:%p,%@,%@----str1:%p,%@,%@----str2:%p,%@,%@",mulStr,mulStr,NSStringFromClass([mulStr class]),mulStr1,mulStr1,NSStringFromClass([mulStr1 class]),mulStr2,mulStr2,NSStringFromClass([mulStr2 class]));

打印结果如下:

----str:0x600000260180,abc,__NSCFString----str1:0xa000000006362613,abc,NSTaggedPointerString----str2:0x6000002601c0,abc,__NSCFString

通过上面的打印结果可以看出来可变字符串经过copy和mutableCopy之后都创建了新的对象。经过copy之后得到的是不可变字符串,经过mutableCopy之后 得到的是可变字符串。

为什么都会生成对象呢???因为可变字符串本来就是可以改变的,为了改变互不干扰,从而生成新的对象,符合拷贝的目的。

二:NSArray、NSMutableArray容器对象分析

首先容器对象和非容器对象一样同样遵从下面的总结:

如果对一不可变对象复制,copy是指针复制(浅拷贝)、mutableCopy就是对象复制(深拷贝)。

如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。

1.NSArray的copy和mutableCopy 

NSArray *array = [[NSArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"a"],@"b",@"c", nil];

NSArray *array1 = [array copy];

NSMutableArray *array2 = [array mutableCopy];

// NSArray *array3 = [array mutableCopy];

NSArray *array3 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]];

NSLog(@"----array:%p,----array1:%p,-----array2:%p,----array3:%p",array,array1,array2,array3);

NSMutableString *str1 = [array objectAtIndex:0];

[str1 appendString:@"hahhaha"];

[array2 insertObject:@"111111" atIndex:0];

NSMutableString *str2 = [array2 objectAtIndex:1];

[str2 appendString:@"111111"];

NSLog(@"----array:%@,----array1:%@,-----array2:%@,----array3:%@",array,array1,array2,array3);

打印结果如下:

 ----array:0x608000242070,----array1:0x608000242070,-----array2:0x608000242b50,----array3:0x608000242d90

 ----array:(

ahahhaha111111,

b,

c

),----array1:(

ahahhaha111111,

b,

c

),-----array2:(

111111,

ahahhaha111111,

b,

c

),----array3:(

a,

b,

c

)

通过上面的打印可以看出来NSArray 经过Copy之后没有创建对象,经过mutableCopy之后创建了新的对象,具体原因和NSString一样,但是里面的元素对象还是指针拷贝,要想做到对象拷贝,可以使用归档的方法。

2.NSMutableArray 的copy和MutableCopy

NSMutableArray *mulArray = [[NSMutableArray alloc]initWithObjects:[NSMutableString stringWithFormat:@"abc"],@"def", nil];

NSMutableArray *mulArray1 = [mulArray copy];

NSMutableArray *mulArray2 = [mulArray mutableCopy];

NSLog(@"----array:%p,----arrar1:%p,----array2:%p",mulArray,mulArray1,mulArray2);

NSMutableString *mulstr = [mulArray objectAtIndex:0];

[mulstr appendString:@"abc"];

NSLog(@"----array:%@,-----array1:%@,-----array2:%@",mulArray,mulArray1,mulArray2);

NSLog(@"----array:%@,-----array1:%@,-----array2:%@",NSStringFromClass([mulArray class]) ,NSStringFromClass([mulArray1 class]),NSStringFromClass([mulArray2 class]));

打印结果如下:

----array:0x60000005af40,----arrar1:0x60000002b1a0,----array2:0x60000005ad60

----array:(

abcabc,

def

),-----array1:(

abcabc,

def

),-----array2:(

abcabc,

def

)

通过上面的打印可以看出来NSArray 经过Copy和mutableCopy之后都创建新的对象,具体原因和NSString一样,但是里面的元素对象还是指针拷贝,要想做到对象拷贝,可以使用归档的方法。

但是大家还要牢记一点:NSMutableArray多次copy每次都会新建对象而NSArray多次copy只新建一次对象。

4.总结

正是因为调用copy方法有时候会生成一个新的对象, 有时候不会生成一个新的对象所以:

如果没有生成新的对象, 我们称之为浅拷贝, 本质就是指针拷贝

如果生成了新的对象, 我们称之为深拷贝, 本质就是会创建一个新的对象

最后:最重要的还是记住拷贝的目的,这样理解深浅拷贝都会变得非常简单,改变原来的内容不影响副本,改变副本也不影响原来的内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容