zoukankan      html  css  js  c++  java
  • 关于深复制和浅复制

    1.先看两者的区别

    深复制(深拷贝,内容拷贝,deep copy)

    源对象和副本对象是不同的两个对象

    源对象引用计数器不变, 副本对象计数器为1(因为是新产生的)

    本质是:产生了新的对象

    浅复制(浅拷贝,指针拷贝,shallow copy)

    源对象和副本对象是同一个对象

    源对象(副本对象)引用计数器 + 1, 相当于做一次retain操作

    本质是:没有产生新的对象

    一句话总结就是:深复制产生了新的对象,浅复制没有产生新对象,而是原对象做了一次retain操作

    2.以NSString 和NSMutableString为例做copy 和mutableCopy总结

    //string   copy   浅复制
      NSString *str1 = [NSString stringWithFormat:@"addd"];
       NSMutableString *str2 = [str1 copy];
        //str1 = 0x7f9cc9c0ef20,count = 2
        //str2 = 0x7f9cc9c0ef20, coutn =2
        
        //string     mutablecopy 深复制
        NSString *str1 = [NSString stringWithFormat:@"addd"];
       
       NSMutableString *str2 = [str1 mutableCopy];
        //str1 = 0x7f8583e1c560,count = 1
        //str2 = 0x7f8583e1c400, coutn =1
        
        //mutableString copy  深复制
        NSMutableString *str1 = [NSMutableString stringWithFormat:@"addd"];
        
        NSMutableString *str2 = [str1 copy];
        
        //str1 = 0x7fbce2f21560,count = 1
        //str2 = 0x7fbce2f1ee40, coutn =1
        
        //mutableString mutablecopy 深复制
        NSString *str1 = [NSString stringWithFormat:@"addd"];
        NSMutableString *str2 = [str1 mutableCopy];
        //str1 = 0x7fea5a555d80,count = 1
        //str2 = 0x7fea5a538020, coutn =1
        
        NSLog(@"str1 = %p,count = %lu",str1,str1.retainCount);
        NSLog(@"str2 = %p, coutn =%lu ",str2,str2.retainCount);

    从以上代码可以看出:

    1.只有是NSString 调用了copy 复制给另一个对象(不论是NSString,或NSMutableString)才是浅复制,其他情况都是深复制;

    2.            copy :   创建的是不可变副本(很重要

        mutableCopy:  创建的是可变副本

    3.分析:由于copy创建对象的不可变性 ,并且调用copy的对象如果是NSString类型,原对象和副本(新)对象都不可变了,

      从内存利用率上来讲,他俩就指向同一个内存空间比较合理,也就是新旧两个指针变量都指向原来的对象(内存),

      这个对象(内存)的计数器只需加1就皆大欢喜了,这就是所谓浅复制;

    一句话:只有源对象和副本对象都不可变时,才是浅复制,其它都是深复制

    最后稍微引申下@prpoerty属性中NSString为啥用copy而不用retain:

    copy 和 retain 的关键set方法实现大家都该知道:都是先release旧值,再copy 或retain新值,

    retain 新值就是把传入的新值计数器加1,然后把对象复值给属性,很明显他俩都指向同一个对象,

    外边的对象变了,内部的属性只肯定也跟着变,这对一般的对象还可以,但对NSString对象就不靠谱了:我拿着传进来的对象还没用,外边的NSString就变了,我里边的NSString类型属性也跟着变了,这就出问题了,必须要保证你外边的NSString可以变,但穿进来时是什么就是什么不能再跟着外边变了。

    这就需要用到copy的copy过后新对象不会改变的特性了。不管你是可变的还是不可变的NSString传进来,我的set方法里一copy,那么属性就板上定订不会变了

    就是这copy新值让人困惑,卧槽啊,不是说copy是浅复

  • 相关阅读:
    linux 下监控进程流量情况命令 NetHogs
    tensorflow学习官网地址
    zabbix 报表
    zabbix性能优化等
    awk输出匹配内容的所在列数
    zabbix api支持的数据类型
    ss命令能识别的TCP状态的关键字
    数据分析初识、Anaconda安装、Juypyter notebook配置与快捷键
    Flask框架(五)之SQLAlchemy
    Flask框架(四)之信号
  • 原文地址:https://www.cnblogs.com/shuizhuqing/p/4486565.html
Copyright © 2011-2022 走看看