zoukankan      html  css  js  c++  java
  • IOS的浅拷贝和深拷贝

    什么是深拷贝和浅拷贝

    浅拷贝:就是指针的复制,拷贝的指针跟原指针指向内存中的同一个位置的对象。至于对象的引用计数值是否+1,就是看拷贝的指针赋给给的变量是Strong类型的,还是week类型的。 如果是 strong类型,那么被拷贝的对象的内存计数值会+1,如果赋值给了weak类型的变量,那么被拷贝的对象的内存计数值会保持不便。

    深拷贝:将内存中的对象拷贝一份,放到一个新的位置,并将这个指向这个新位置的指针指赋值给另外一个变量。

    判断拷贝类型,关键的依据是指针所指向的对象在内存中的地址。

    IOS中的拷贝方式有两种拷贝,一种是 copy ,另外一种是mutableCopy。 至于这两种方法对产生的拷贝属于'浅拷贝'还是'深拷贝'是要根据具体情况来决定的。

    1:对于非容器类对象的拷贝。

    什么是非容器类对象。 类似于  NSString ,NSNumber 等这种只能存储一个值的对象就叫做非容器类对象。

    1.1:非容器类不可变对象的拷贝

        NSString *string = @"非容器类对象";

            NSString *stringCopy = [string copy];

            NSMutableString *MStringCopy = [string copy];

            NSString *stringMutCopy = [string mutableCopy];

            NSMutableString *MStringMutCopy = [string mutableCopy];

            NSLog(@"对象的地址:%p",string);            //对象的地址:0x107d7e6d8

            NSLog(@"对象的地址:%p",stringCopy);         //对象的地址:0x107d7e6d8

            NSLog(@"对象的地址:%p",MStringCopy);      //对象的地址:0x107d7e6d8

            NSLog(@"对象的地址:%p",stringMutCopy);     //对象的地址:0x7f9f397022e0

            NSLog(@"对象的地址:%p",MStringMutCopy);    //对象的地址:0x7f9f395043c0

    通过上面的打印结果来分析:

    对于非容器类不可变对象:copy是属于浅拷贝,mutableCopy属于深拷贝

    为什么会这样呢?

    复制之后,IOS也是考虑到了内存控制和变量之间不相互干扰的原则。 对于内存中不可变的对象,因为对象不可变,所以对于使用这个对象的变量来说,指向同一个内存位置,即满足了使用相同的内容,又不必要开辟新内存空间,达到了节省内存空间的目的。

    1.2:非容器类可变对象的拷贝

            NSMutableString *string = [NSMutableString stringWithString:@"非容器类可变对象"];

            NSString *stringCopy = [string copy];

            NSMutableString *MStringCopy = [string copy];

            NSString *stringMutCopy = [string mutableCopy];

            NSMutableString *MStringMutCopy = [string mutableCopy];

            NSLog(@"对象的地址:%p",string);       //对象的地址:0x7fc2c9f054a0

            NSLog(@"对象的地址:%p",stringCopy);     //对象的地址:0x7fc2c9d08800

            NSLog(@"对象的地址:%p",MStringCopy);    //对象的地址:0x7fc2c9d168e0

            NSLog(@"对象的地址:%p",stringMutCopy);    //对象的地址:0x7fc2c9c065e0

            NSLog(@"对象的地址:%p",MStringMutCopy);   //对象的地址:0x7fc2c9d179b0

    可以看到上面的对象在内存中的地址都不相同,也就是说他们发生的拷贝都是深拷贝

    总结:

    1:对于非容器类不可变对象的拷贝,copy方法属于浅拷贝,mutableCopy属于深拷贝

    2:对于非容器类可变对象的拷贝, copy方法属于深拷贝,mutableCopy也属于深拷贝

    这样处理的依据是:对象之间的不干扰以及内存节省的原则

    2:对于容器类对象的拷贝

    什么是容器类对象。就是可以存储其他对象的对象。比如:NSArray,NSDictionary等等

    2.1:不可变容器类对象的拷贝

            NSArray *ary = [NSArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];

            NSArray *aryCopy = [ary copy];

            NSMutableArray *MAryCopy = [ary copy];

            NSArray *aryMCopy = [ary mutableCopy];

            NSMutableArray *MAryMCopy = [ary mutableCopy];

            NSLog(@"对象的地址:%p",ary);           //0x7fedc25058c0

            NSLog(@"对象的地址:%p",aryCopy);        //0x7fedc25058c0

            NSLog(@"对象的地址:%p",MAryCopy);       //0x7fedc25058c0

            NSLog(@"对象的地址:%p",aryMCopy);       //0x7fedc250b5f0

            NSLog(@"对象的地址:%p",MAryMCopy);      //0x7fedc2414310

    根据对象在内存中的地址可以,

    对于不可变容器类对象为,copy为浅拷贝,mutableCopy为神拷贝

    2.2:可变容器类对象的拷贝

            NSMutableArray *ary = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4", nil];

            NSArray *aryCopy = [ary copy];

            NSMutableArray *MAryCopy = [ary copy];

            NSArray *aryMCopy = [ary mutableCopy];

            NSMutableArray *MAryMCopy = [ary mutableCopy];

            NSLog(@"对象的地址:%p",ary);            //0x7fe703703d90

            NSLog(@"对象的地址:%p",aryCopy);         //0x7fe703706720

            NSLog(@"对象的地址:%p",MAryCopy);      //0x7fe703706180

            NSLog(@"对象的地址:%p",aryMCopy);      //0x7fe7037061b0

            NSLog(@"对象的地址:%p",MAryMCopy);     //0x7fe703706200

    通过拷贝后对象在内存中的地址可以看到,对于可变容器类对象的拷贝,不管copy和mutableCopy都是深拷贝。

     

     

     

  • 相关阅读:
    【Java并发】详解 AbstractQueuedSynchronizer
    【Java 并发】详解 ThreadLocal
    【应用】Markdown 在线阅读器
    【HTML5】Canvas 内部元素添加事件处理
    【HTML5】Canvas 实现放大镜效果
    分享一款Markdown的css样式
    【Pthreads】Pipeline Model(Assembly Line)示例
    简单实现依赖注入(无框架)
    JavaWeb 简单实现客户信息管理系统
    Python中模块的发布与安装
  • 原文地址:https://www.cnblogs.com/xingchen/p/5740821.html
Copyright © 2011-2022 走看看