iOS 深拷贝和浅拷贝

浅拷贝就是拷贝后,并没有进行真正的复制,拷贝后的对象和原对象都指向同一块内存地址

深拷贝是真正的复制了一份,复制的对象指向了新的内存地址

浅拷贝就相当于自己的影子,而深拷贝则是克隆的你

//注意
//copy 在拷贝不可变对象的时候为浅拷贝,但是拷贝可变对象的时候为深拷贝
//mutablecopy 始终为深拷贝

copy

NSLog(@"-----------------copy-----------------");
//不可变对象
NSString *str = @"字符串";
NSString *copyStr = str.copy;
NSLog(@"\n不可变字符串");
NSLog(@"\nstr_p:%p,\ncopyStr_p:%p",str,copyStr);
//    不可变字符串
//    str_p:0x1043b72a8,
//    copyStr_p:0x1043b72a8

NSArray *array = [NSArray array];
NSArray *copyArray = array.copy;
NSLog(@"\n不可变数组");
NSLog(@"\narray_p:%p,\ncopyArray_p:%p",array,copyArray);
//    不可变数组
//    array_p:0x6040000091f0,
//    copyArray_p:0x6040000091f0

//copy在拷贝不可变对象的时候为浅拷贝,浅拷贝的对象共用同一块内存地址



//可变对象
NSMutableString *mutablestr = [[NSMutableString alloc] initWithString:@"可变字符串"];
NSString *copyMutablestr = mutablestr.copy;
NSLog(@"\n可变字符串");
NSLog(@"\nmutablestr_p:%p,\ncopyMutablestr_p:%p",mutablestr,copyMutablestr);
//    可变字符串
//    mutablestr_p:0x60000005a700,
//    copyMutablestr_p:0x600000059c50

NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
NSArray *copyMutableArray = mutableArray.copy;//可变数组copy后,虽然为新的对象,但是对象类型是NSArray而不是NSMutableArray
NSLog(@"\n可变数组");
NSLog(@"\nmutableArray_p:%p,\ncopyMutableArray_p:%p",mutableArray,copyMutableArray);
//    可变数组
//    mutableArray_p:0x604000457a90,
//    copyMutableArray_p:0x6040000091f0

由此可得出结论
copy在拷贝可变对象的时候为深拷贝,深拷贝的对象为全新的对象,有自己的内存地址
拷贝不可变对象的时候为浅拷贝,浅拷贝的对象共用同一块内存地址

mutablecopy

NSLog(@"-----------------mutableCopy-----------------");
NSString *str = @"字符串";
NSString *mutableCopyStr = str.mutableCopy;
NSLog(@"\n不可变字符串");
NSLog(@"\nstr_p:%p,\nmutableCopyStr:%p",str,mutableCopyStr);
//    不可变字符串
//    str_p:0x10aa092c8,
//    mutableCopyStr:0x600000041f20

NSArray *array = [NSArray array];
NSArray *mutablecopyArray = array.mutableCopy;
NSLog(@"\n不可变数组");
NSLog(@"\narray_p:%p,\nmutablecopyArray_p:%p",array,mutablecopyArray);
//    不可变数组
//    array_p:0x6000000034e0,
//    mutablecopyArray_p:0x604000256980

//可变对象
NSMutableString *mutablestr = [[NSMutableString alloc] initWithString:@"可变字符串"];
NSString *mutablecopyMutablestr = mutablestr.mutableCopy;
NSLog(@"\n可变字符串");
NSLog(@"\nmutablestr_p:%p,\nmutablecopyMutablestr_p:%p",mutablestr,mutablecopyMutablestr);
//    可变字符串
//    mutablestr_p:0x600000241f50,
//    mutablecopyMutablestr_p:0x60000005f440


NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
NSArray *mutablecopyMutableArray = mutableArray.mutableCopy;//
NSLog(@"\n可变数组");
NSLog(@"\nmutableArray_p:%p,\nmutablecopyMutableArray_p:%p",mutableArray,mutablecopyMutableArray);
//    可变数组
//    mutableArray_p:0x604000255060,
//    mutablecopyMutableArray_p:0x6040002555d0

由此可得出结论:mutablecopy都是深拷贝,拷贝后的对象都有自己的内存地址

当容器内有元素的时候,对对象的copy和mutablecopy会对里面的元素有啥影响呢?

NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],@"2", nil];
NSMutableArray *copyMutableArray = mutableArray.copy;
NSMutableArray *mutableCopyMutableArray = mutableArray.mutableCopy;

NSLog(@"mutableArray_p:%p,copyMutableArray_p:%p,mutableCopyMutableArray_p:%p",mutableArray,copyMutableArray,mutableCopyMutableArray);
//mutableArray_p:0x60000025c0e0,
//copyMutableArray_p:0x600000231980,
//mutableCopyMutableArray_p:0x60000025e120

//拷贝前
NSLog(@"mutableArray_object1_p:%p,mutableArray_object2_p:%p",mutableArray[0],mutableArray[1]);
//mutableArray_object1_p:0x60000025da90,
//mutableArray_object2_p:0x10d9b34c8

//copy后
NSLog(@"copyMutableArray_object1_p:%p,copyMutableArray_object2_p:%p",copyMutableArray[0],copyMutableArray[1]);
//copyMutableArray_object1_p:0x60000025da90,
//copyMutableArray_object2_p:0x10d9b34c8

//mutablecopy后
NSLog(@"mutableCopyMutableArray_object1_p:%p,mutableCopyMutableArray_object2_p:%p",mutableCopyMutableArray[0],mutableCopyMutableArray[1]);
//mutableCopyMutableArray_object1_p:0x60000025da90,
//mutableCopyMutableArray_object2_p:0x10d9b34c8

由此可见,copy和mutablecopy对于容器内的元素是浅拷贝

如果你想对容器做完全拷贝(也就是容器深拷贝,元素也深拷贝)该怎么办呢?可以使用归档的办法(如果是自定义对象,需要实现NSCoding协议,不然会crash)。

NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"1"],@"2", nil];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
NSArray *mutablecopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

NSLog(@"array_p:%p,array_objec1_p:%p,array_objec2_p:%p",array,array[0],array[1]);
//array_p:0x6040002386c0,
//array_objec1_p:0x60400025f590,
//array_objec2_p:0x10d17b4c8
NSLog(@"mutablecopyArray_p:%p,mutablecopyArray_objec1_p:%p,mutablecopyArray_objec2_p:%p",mutablecopyArray,mutablecopyArray[0],mutablecopyArray[1]);
//mutablecopyArray_p:0x604000238780,
//mutablecopyArray_objec1_p:0x60400005ce60,
//mutablecopyArray_objec2_p:0xa000000000000321

自定义对象的归档协议实现

#import "Student.h"
@interface Student ()<NSCoding>
@property (nonatomic,copy)NSString *age;
@end
@implementation Student

/**********编码/解码***********/
//解码的时候调用
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self.age = [aDecoder decodeObjectForKey:@"age"];
    return self;
}
//编码的时候调用
- (void)encodeWithCoder:(NSCoder *)aCoder
{
    [aCoder encodeObject:self.age forKey:@"age"];
}
@end

自定义对象的copy和mutablecopy,需要实现NSCopying、NSMutableCopying协议,不然使用copy和mutablecopy方法会crash

#import "Student.h"
@interface Student ()<NSCopying,NSMutableCopying>
@property (nonatomic,copy)NSString *age;
@end
@implementation Student

/******浅拷贝/深拷贝*******/
- (id)copyWithZone:(NSZone *)zone
{

    Student *s = [[[self class] allocWithZone:zone] init];
    s.age = self.age;
    return s;
}


- (id)mutableCopyWithZone:(NSZone *)zone
{

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

推荐阅读更多精彩内容

  • 在工作中,有时会涉及到深拷贝和浅拷贝的内容,发现有些地方理解的不够透彻,所以在网上搜集资料总结一下,主要分四个方面...
    LeverTsui阅读 3,557评论 3 5
  • 一、名词解释 1、 浅拷贝(shallow copy):只是增加了一个对被引用对象的一个指向,即指针拷贝,只是re...
    远方的枫叶阅读 350评论 0 1
  • 深拷贝:内容拷贝,拷贝出来的对象和之前的对象的地址不一样。 浅拷贝:指针拷贝,拷贝出来的对象和之前的对象的地址一样...
    Persistence__阅读 271评论 0 0
  • 1、对象拷贝有两种方式:浅复制和深复制。顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针;深复制是直接...
    滴答大阅读 761评论 0 2
  • 深拷贝和浅拷贝这个问题在面试中常常被问到,而在实际开发中,只要稍有不慎,就会在这里出现问题。尤其对于初学者来说,我...
    西门淋雨阅读 1,784评论 0 1