zoukankan      html  css  js  c++  java
  • 深复制与浅复制

      深复制与浅复制 需要遵守NSCopying, NSMutableCopying 2个协议

    什么是copy
    Copy的字面意思是“复制”、“拷贝”,是一个产生副本的过程
    
    常见的复制有:文件复制
    作用:利用一个源文件产生一个副本文件
    特点:
    修改源文件的内容,不会影响副本文件
    修改副本文件的内容,不会影响源文件
    
    OC中的copy
    作用:利用一个源对象产生一个副本对象
    特点:
    修改源对象的属性和行为,不会影响副本对象
    修改副本对象的属性和行为,不会影响源对象
    
    如何使用copy功能
    一个对象可以调用copy或mutableCopy方法来创建一个副本对象
    copy : 创建的是不可变副本(如NSString、NSArray、NSDictionary)
    mutableCopy :创建的是可变副本(如NSMutableString、NSMutableArray、NSMutableDictionary)
    
    使用copy功能的前提
    copy : 需要遵守NSCopying协议,实现copyWithZone:方法
    @protocol NSCopying
    - (id)copyWithZone:(NSZone *)zone;
    @end
    
    mutableCopy : 需要遵守NSMutableCopying协议,实现mutableCopyWithZone:方法
    @protocol NSMutableCopying
    - (id)mutableCopyWithZone:(NSZone *)zone;
    @end 
    
    深复制(深拷贝,内容拷贝,deep copy)
    源对象和副本对象是不同的两个对象
    源对象引用计数器不变, 副本对象计数器为1(因为是新产生的)
    本质是:产生了新的对象
    
    浅复制(浅拷贝,指针拷贝,shallow copy)
    源对象和副本对象是同一个对象
    源对象(副本对象)引用计数器 + 1, 相当于做一次retain操作
    本质是:没有产生新的对象
    

     

    实例1 NSString和NSMutableString:

    NSString *str1 = @"abc";
        NSString *str2 = @"abc";
        
        BOOL isEquals = str1==str2?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSString *str3 = [str1 copy];
        isEquals = str3==str2?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSMutableString *str4 = [str1 mutableCopy];
        isEquals = str4==str1?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSLog(@"-----------------------");
        
        NSString *str5 = @"abc";
        NSMutableString *str6 = [NSMutableString stringWithFormat:@"abc"];
        isEquals = str5==str6?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSString *str7 = [str6 copy];
        isEquals = str7==str2?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSMutableString *str8 = [str6 mutableCopy];
        isEquals = str8==str6?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
    

     运行结果:

    2015-01-01 14:48:07.742 深复制与浅复制[934:56160] =相同=
    2015-01-01 14:48:07.743 深复制与浅复制[934:56160] =相同=
    2015-01-01 14:48:07.743 深复制与浅复制[934:56160] =不相同=
    2015-01-01 14:48:07.743 深复制与浅复制[934:56160] -----------------------
    2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=
    2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=
    2015-01-01 14:48:07.744 深复制与浅复制[934:56160] =不相同=
    Program ended with exit code: 0
    

     注意:NSString copy产生的不可变数据对象也是指向原对象,上面str1和str3

    实例2 NSArray和NSMutableArray:

     NSArray *array1 = @[@1,@2,@3];
        NSArray *array2 = @[@1,@2,@3];
        
        BOOL isEquals = array1 == array2 ? YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSArray *array3 = [array1 copy];
        isEquals = array3 == array1 ? YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
    
        NSMutableArray *array4 = [array1 mutableCopy];
        isEquals = array4 == array1 ? YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
    //    NSLog(@"%@",array1);
    //    NSLog(@"%@",array4);
        [array4 addObject:@4];
    //    NSLog(@"%@",array1);
        NSLog(@"%@",array4);
        
        NSLog(@"--------------------------");
        
        NSMutableArray *array5 = [NSMutableArray arrayWithObjects:@1,@2,@3, nil];
      
        NSArray *array6 = [array5 copy];
        isEquals = array5 == array6 ? YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        NSMutableArray *array8 = [array5 mutableCopy];
        isEquals = array5 == array8 ? YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
    //    NSLog(@"%@",array8);
        [array8 addObject:@4];
    //    NSLog(@"%@",array5);
        NSLog(@"%@",array8);
    

     运行结果:

    2015-01-01 15:00:30.950 深复制与浅复制[980:59234] =不相同=
    2015-01-01 15:00:30.951 深复制与浅复制[980:59234] =相同=
    2015-01-01 15:00:30.951 深复制与浅复制[980:59234] =不相同=
    2015-01-01 15:00:30.952 深复制与浅复制[980:59234] (
        1,
        2,
        3,
        4
    )
    2015-01-01 15:00:30.952 深复制与浅复制[980:59234] --------------------------
    2015-01-01 15:00:30.952 深复制与浅复制[980:59234] =不相同=
    2015-01-01 15:00:30.952 深复制与浅复制[980:59234] =不相同=
    2015-01-01 15:00:30.952 深复制与浅复制[980:59234] (
        1,
        2,
        3,
        4
    )
    Program ended with exit code: 0
    

     注意:NSArray copy产生的不可变数据对象也是指向原对象,上面array1和array3

    实例4 NSDictionary和NSMutableDictionary 跟上面情况一样:

    实例5:测试不管产生可变还是不可变对象,数组中存储内容对象都还是指向同一份对象

    @interface Person : NSObject //<NSCopying, NSMutableCopying>
    
    @property (nonatomic,copy) NSString *name;
    @property (nonatomic,assign) int age;
    
    - (void)eat;
    
    - (instancetype)initWithName:(NSString *)name age:(int)age;
    + (instancetype)personWithName:(NSString *)name age:(int)age;
    
    @end
    
    #import "Person.h"
    
    @implementation Person
    
    - (void)eat{
        NSLog(@"%s",__func__);
    }
    
    + (instancetype)personWithName:(NSString *)name age:(int)age{
        return [[self alloc] initWithName:name age:age];
    }
    
    - (instancetype)initWithName:(NSString *)name age:(int)age{
        if (self == [super init]) {
            self.name = name;
            self.age = age;
        }
        return self;
    }
    
    - (NSString *)description{
        return [NSString stringWithFormat:@"name=%@ age=%d",_name,_age];
    }
    
    //- (id)copyWithZone:(NSZone *)zone{
    //    Person *person = [[Person allocWithZone:zone] init];
    //    person.name = [self.name copy];
    //    person.age = self.age;
    //    return person;
    //}
    //
    //- (id)mutableCopyWithZone:(NSZone *)zone{
    //    Person *person = [[Person allocWithZone:zone] init];
    //    person.name = [self.name mutableCopy];
    //    person.age = self.age;
    //    return person;
    //}
    
    @end
    
    Person *p1 = [Person personWithName:@"zhangsan" age:20];
        Person *p2 = [Person personWithName:@"lisi" age:21];
        Person *p3 = [Person personWithName:@"wangwu" age:22];
        
        NSMutableArray *array1 = [NSMutableArray arrayWithObjects:p1,p2,p3, nil];
        NSLog(@"%@",array1);
        p1.name = @"zhangsan111";
        NSLog(@"%@",array1);
        
        NSArray *array2 = [array1 copy];
        NSLog(@"%@",array2);
        
        BOOL isEquals = array1 == array2?YES:NO;
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
        
        isEquals = array1[0] == array2[0];
        NSLog(@"=%@=",isEquals?@"相同":@"不相同");
    

     运行结果:

    2015-01-01 15:18:58.814 深复制与浅复制[1100:64607] (
        "name=zhangsan age=20",
        "name=lisi age=21",
        "name=wangwu age=22"
    )
    2015-01-01 15:18:58.815 深复制与浅复制[1100:64607] (
        "name=zhangsan111 age=20",
        "name=lisi age=21",
        "name=wangwu age=22"
    )
    2015-01-01 15:18:58.815 深复制与浅复制[1100:64607] (
        "name=zhangsan111 age=20",
        "name=lisi age=21",
        "name=wangwu age=22"
    )
    2015-01-01 15:18:58.816 深复制与浅复制[1100:64607] =不相同=
    2015-01-01 15:18:58.816 深复制与浅复制[1100:64607] =相同=
    

     说明复制后2个数组中存储的内容对象是相同的

  • 相关阅读:
    C#中的代理(Delegate)
    动态栈C语言
    AMS算法
    动态队列实现C语言
    带头结点的循环单链表C语言
    静态栈C语言
    不带头结点的单链表C语言实现
    带头结点的双向循环链表C语言
    带头节点的单链表C语言实现
    使用函数指针模拟C++多态
  • 原文地址:https://www.cnblogs.com/HJiang/p/4197222.html
Copyright © 2011-2022 走看看