• 关于深复制和浅复制


    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是浅复

  • 相关阅读:
    Spring MVC 程序首页的设置
    绿色版Tomcat 启动 + 停止 + 随系统自动启动
    Lazy Load, 延迟加载图片的 jQuery 插件
    ibatis参数传递小技巧
    SpringMVC接收页面表单参数-java-电脑编程网
    用 JS 点击左右按钮 使图片切换
    JS数组方法汇总 array数组元素的添加和删除
    关于jQuery UI 使用心得及技巧
    MySQL查询in操作 查询结果按in集合顺序显示_Mysql_脚本之家
    JSTL c标签,fn标签,fmt标签
  • 原文地址:https://www.cnblogs.com/shuizhuqing/p/4486565.html
Copyright © 2020-2023  润新知