iOS 浅拷贝和深拷贝

1、对象拷贝,使用关键字 copy 和 mutableCopy,使用这两个方法即可复制已存在的对象
自定义类想要具备可复制功能,必须实现NSCopying 或 NSMutableCopy
copy 返回的是不可变对象,mutableCopy 返回的是可变对象
让自定义的类具有 copy 和 mutableCopy,这个类需遵守NSCopying、NSMutableCopying协议并实现协议方法
2、浅拷贝只是复制指向对象的指针,不会开辟新的内存空间,两个指针指向同一块内存空间

NSArray *array = [NSArray arrayWithObject:@"1"];
NSLog(@"%p  -- %p",array,[array copy]);
// 0x6000006f6d30 
// 0x6000006f6d30
// %p 打印对象内存地址

3、深拷贝会拷贝对象的具体内容,然后指向一块新的内存地址
常见的几种例子

// 第一种情况 
@property (nonatomic, strong) NSArray *list;

NSMutableArray *array = [NSMutableArray arrayWithObject:@"1"];
self.list = array;
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"%p -- %p",self.list, array);
// 数组内容一样,内存地址一样
    
[array addObject:@"2"];
    
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"%p -- %p",self.list, array);
// 修改数组后,数组内容一样,内存地址也一样
// 此种情况 为浅拷贝
// 第二种情况 
@property (nonatomic, copy) NSArray *list;

NSMutableArray *array = [NSMutableArray arrayWithObject:@"1"];
self.list = array;
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"%p -- %p",self.list, array);
// 数组内容一样,内存地址不一样
    
[array addObject:@"2"];
    
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"%p -- %p",self.list, array);
// 修改数组后,数组内容不一样,内存地址也不一样
// 此种情况为深拷贝
// 第三种情况
@property (nonatomic, strong) NSMutableArray *list;

NSMutableArray *array = [NSMutableArray arrayWithObject:@"1"];
self.list = array;
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"\n%p \n%p",self.list, array);
// 数组内容一样,内存地址一样
    
[array addObject:@"2"];
    
NSLog(@"%@ -- %@",self.list, array);
NSLog(@"\n%p \n%p",self.list, array);
// 修改数组后,数组内容一样,内存地址也一样
// 此种情况 为浅拷贝

注意:@property 中可变类型不能使用 copy 修饰,@property 是由 ivar(属性变量) + getter + setter 方法组成的,self.list 会调用 setter 方法,setter 方法中有 _list = [list copy]; 会将可变类型变为不可变类型,self.list 在调用增、删、改等可变对象的方法时,会crash,找不到方法,报错误:unrecognized selector sent to instance 0x600001583330

// 第四种情况
NSArray *list = [NSArray arrayWithObject:@"1"];
NSArray *array = [list copy];
    
NSLog(@"\n%p\n%p",list,array);
// 内存地址一样
// 浅拷贝
// 第五种情况
NSArray *list = [NSArray arrayWithObject:@"1"];
NSMutableArray *array = [list mutableCopy];
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 内容一样,内存地址不一样
    
[array addObject:@"2"];
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 修改后,内容不一样,内存地址也不一样
// 深拷贝
// 第六种情况
NSMutableArray *list = [NSMutableArray arrayWithObject:@"1"];
NSArray *array = [list copy];
    
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 内容一样,内存地址不一样
    
[list addObject:@"2"];
    
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 修改后,内容不一样,内存地址也不一样
// 深拷贝
// 第七种情况
NSMutableArray *list = [NSMutableArray arrayWithObject:@"1"];
NSMutableArray *array = [list mutableCopy];
    
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 内容一样,内存地址不一样
    
[list addObject:@"2"];
    
NSLog(@"%@ -- %@",list,array);
NSLog(@"\n%p\n%p",list,array);
// 修改后,内容不一样,内存地址也不一样
// 深拷贝
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 13,805评论 1 32
  • 深拷贝和浅拷贝这个问题在面试中常常被问到,而在实际开发中,只要稍有不慎,就会在这里出现问题。尤其对于初学者来说,我...
    weyan阅读 3,332评论 0 1
  • 对于不可变的集合类对象进行 copy 操作,只是改变了指针,其内存地址并没有发生变化;进行 mutableCopy...
    魔性佛心阅读 3,828评论 0 0
  • 《孟子﹒告子下》讲,“夫道若大路然,岂难知哉?人病不求耳。” 就是讲,道理就像大路一样,哪里难于知道呢?只怕人不去...
    关观阅读 1,716评论 0 2
  • 安装YouCompleteMe的步骤 用vundle中的安装太慢,所以自己手动安装检查是否安装clang、g++、...
    54Fire阅读 12,011评论 2 0