美文网首页
深拷贝和浅拷贝

深拷贝和浅拷贝

作者: edison0428 | 来源:发表于2017-07-21 15:54 被阅读9次

对象拷贝有两种方式:浅复制和深复制。顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针;深复制是直接拷贝整个对象内存到另一块内存中

浅复制(shallow copy):在浅复制操作时,对于被复制对象的每一层都是指针复制。
深复制(one-level-deep copy):在深复制操作时,对于被复制对象,至少有一层是深复制。
完全复制(real-deep copy):在完全复制操作时,对于被复制对象的每一层都是对象复制。

在非集合类对象中:对immutable对象进行copy操作,是指针复制,mutableCopy操作时内容复制;对mutable对象进行copy和mutableCopy都是内容复制。用代码简单表示如下:

[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //深复制
[mutableObject copy] //深复制
[mutableObject mutableCopy] //深复制

在集合类对象中,对immutable对象进行copy,是指针复制,mutableCopy是内容复制;对mutable对象进行copy和mutableCopy都是内容复制。但是:集合对象的内容复制仅限于对象本身,对象元素仍然是指针复制。用代码简单表示如下:

[immutableObject copy] // 浅复制
[immutableObject mutableCopy] //单层深复制
[mutableObject copy] //单层深复制
[mutableObject mutableCopy] //单层深复制

copy:创建的是不可变副本(NSString,NSArray,NSDictionary)
mutableCopy:创建的是可变副本(NSMutableString,NSMutableArray,NSMutableDictionary)

容器类的深拷贝实现

  • 可以通过归解档生成两份完全独立的对象,但是前提是对象必须支持 NSCoding
为什么字符串要用copy

上代码解释,先用strong试试


@interface ViewController ()

@property(nonatomic,strong)NSString*whyStringUserCopyStr;

@end


@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [self whyStringUserCopy];
}

-(void)whyStringUserCopy{
    
    NSMutableString *string = [NSMutableString string];
    
    [string appendString:@"hello"];
    
    self.whyStringUserCopyStr = string;
    
    NSLog(@"%@",self.whyStringUserCopyStr);
    NSLog(@"string =%p %p whyStringUserCopyStr=%p %p",string,&string,_whyStringUserCopyStr,&_whyStringUserCopyStr);
    [string appendString:@"World"];
    
    NSLog(@"%@",self.whyStringUserCopyStr);

}

打印出的信息

 hello
 string =0x600000245b50 0x7ffee35f92e8 whyStringUserCopyStr=0x600000245b50 0x7f9db3607800
 helloWorld

你会发现self.whyStringUserCopyStr只被赋值了一次,却改变了两次
在看中间打印出string的本身的地址和string指向的地址 以及 whyStringUserCopyStr的本身的地址和whyStringUserCopyStr指向的地址

strong相当于whyStringUserCopyStr指向了可变字符串的地址,所以可变字符串改变了那么whyStringUserCopyStr也会跟着改变,如果用copy将可变字符串重新拷贝一份,重新开辟内存空间,修改可变字符串的值,不会对whyStringUserCopyStr造成影响
因为可变对象的copy是深拷贝

刚刚的演示,我使用了NSMutableString(可变字符串),对mutableString执行copy操作,属于深拷贝,所以开辟的新内存空间,如果使用的是NSString(不可变内存),对NSString进行copy属于浅拷贝,不会开辟新的内存空间,是不是就不会出现这个问题了呢?

接下来使用NSString来进行演示,将属性修饰符再次改回strong

#import "ViewController.h"

@interface ViewController ()

/*    为什么字符串使用copy修饰?
    这里先不使用copy修饰,NSString是OC对象,并且是ARC模式,所以先使用strong来修饰演示
 
 */
@property (nonatomic,strong) NSString *name;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *str = [NSString string];
    str = @"xiaoming";
    
    self.name = str;
    NSLog(@"str:%p,name:%p",str,_name);
    
    str = @"xiaogang";
    NSLog(@"str:%p,name:%p",str,_name);
    
    NSLog(@"%@",_name);
}

@end


打印

str:0x10c937060,name:0x10c937060
str:0x10c9370a0,name:0x10c937060
xiaoming

从结果上看,重新设置str的值后,self.name确实没有受到影响

原因:
将之前的可变字符串变为不可变字符串,因为NSString不支持append添加操作,我这里的两次str赋值操作,其实是让str重新指向了一片内存空间,并不是修改了str原本内存中的值

OC中对象即指针,实际上存储的是内存地址,self.name = str;
实际是将str存储的@"xiaoming"这块地址给了self.name

self.name还指向着@"xiaoming"
所以改变str的指向后,self.name的指向并没有改变,输出没有受到影响

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

  • JavaScript的深拷贝和浅拷贝

    原文 博客原文 大纲 前言1、对深拷贝和浅拷贝的初步认识2、深拷贝和浅拷贝的区别3、浅拷贝存在的缺陷4、深拷贝的实...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

网友评论

      本文标题:深拷贝和浅拷贝

      本文链接:https://www.haomeiwen.com/subject/lgjekxtx.html