美文网首页
Objective-C 浅拷贝、深拷贝、完全拷贝

Objective-C 浅拷贝、深拷贝、完全拷贝

作者: 愤斗的小蚂蚁 | 来源:发表于2022-10-10 19:06 被阅读0次

    在Objective-C中,对对象的拷贝可分为浅拷贝、深拷贝和完全拷贝

    copy、mutableCopy和容器拷贝总结:
    1. copy对于可变对象为深拷贝,对于不可变对象为浅拷贝。
    2. mutableCopy始终是深拷贝。
    3. 对容器进行拷贝,容器内元素始终为浅拷贝。
    浅拷贝、深拷贝和完全拷贝总结:
    1. 浅拷贝(shallow copy):仅仅对内存地址进行了拷贝,并没有对源对象进行拷贝;对于被复制对象的每一层都是指针复制。
    2. 深拷贝(one-level-deep copy):不仅对内存地址进行拷贝,而且对源对象进行拷贝;对于被复制对象,至少有一层是深复制。
    3. 完全深拷贝(real-deep copy):在拷贝的时候,对于被拷贝对象的每一层都进行了拷贝。
    image.png image.png 未命名文件(4).png eg1. 不可变原数据执行 copy,mutableCopy操作: image.png eg2. 可变原数据执行 copy,mutableCopy操作: image.png eg3. 自定义模型(YYModel)数据执行 copy,mutableCopy操作: image.png eg4. 自定义模型(NSCoding,NSCopying)数据归档解档、initWithArray:copyItems:操作: image.png

    eg5. 自定义模型嵌套自定义模型(NSCoding,NSCopying)数据归档解档、initWithArray:copyItems:操作:

    NSMutableArray *array = [[NSMutableArray alloc] init];
    Person *person = [[Person alloc] init];
    person.name = [NSString stringWithFormat:@"张三"];
    person.age = 18;
    [array addObject:person];
    
    // 不完全深拷贝
    NSArray *arrCopy = [array copy];
    NSMutableArray *arrMCopy = [array mutableCopy];
    Person *person1 = [array firstObject];
    Person *perCopy = arrCopy.firstObject;
    Person *perMCopy =arrMCopy.firstObject;
    perCopy.name = @"李四";
    perMCopy.name = @"王五";
    
    NSLog(@"不完全深拷贝");
    NSLog(@"array= %p, person= %@, name= %@", array, person1, person1.name);
    NSLog(@"arrCopy= %p, person= %@, name= %@", arrCopy, perCopy, perCopy.name);
    NSLog(@"arrMCopy= %p, person= %@, name= %@", arrMCopy, perMCopy, perMCopy.name);
    
    //方式1 要在集合对象中实现NSCoding协议
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
    NSArray *array2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];
    
        
    //方式2 要在集合对象中实现NSCopying协议
    NSMutableArray *array3 = [[NSMutableArray alloc] initWithArray:array copyItems:YES];
    
    Person *person2 = [array2 firstObject];
    Person *person3 = [array3 firstObject];
    person2.name = @"李四一";
    person3.name = @"王五一";
    NSLog(@"完全深拷贝");
    NSLog(@"array= %p, person= %@, name= %@", array, person1, person1.name);
    NSLog(@"array2= %p, person= %@, name= %@", array2, person2, person2.name);
    NSLog(@"array3= %p, person= %@, name= %@", array3, person3, person3.name);
    
    /*
    2022-10-12 14:41:37.732284+0800 OC深浅拷贝[52457:290164] 不完全深拷贝
    2022-10-12 14:41:37.732661+0800 OC深浅拷贝[52457:290164] array= 0x10120e030, person= <Person: 0x10073c1e0>, name= 王五
    2022-10-12 14:41:37.732744+0800 OC深浅拷贝[52457:290164] arrCopy= 0x10073a360, person= <Person: 0x10073c1e0>, name= 王五
    2022-10-12 14:41:37.732798+0800 OC深浅拷贝[52457:290164] arrMCopy= 0x10073c1b0, person= <Person: 0x10073c1e0>, name= 王五
    2022-10-12 14:41:37.733398+0800 OC深浅拷贝[52457:290164] 完全深拷贝
    2022-10-12 14:41:37.733525+0800 OC深浅拷贝[52457:290164] array= 0x10120e030, person= <Person: 0x10073c1e0>, name= 王五
    2022-10-12 14:41:37.733596+0800 OC深浅拷贝[52457:290164] array2= 0x10140b8e0, person= <Person: 0x10140b560>, name= 李四一
    2022-10-12 14:41:37.733657+0800 OC深浅拷贝[52457:290164] array3= 0x10140a280, person= <Person: 0x10140a330>, name= 王五一
    **/
    
    @interface Person : NSObject <NSCoding,NSCopying, NSMutableCopying>
    
    @property NSString *name;
    @property NSInteger  age;
    
    @end
    
    @interface Worker : Person <NSCoding,NSCopying>
    
    @property NSString *salary;
    @property Person *leader;
    
    @end
    
    @implementation Person
     
    - (id)copyWithZone:(nullable NSZone *)zone{
     
        Person *copy = [[[self class] allocWithZone:zone] init];
        copy.name = [self.name copy];
        copy.name = [self.name mutableCopy];// copy,mutableCopy二选一
        copy.age = self.age;
        return copy;
    }
    
    - (id)mutableCopyWithZone:(NSZone *)zone {
        
       Person *copy = [[[self class] allocWithZone:zone] init];
        copy.name = [self.name copy];
       copy.name = [self.name mutableCopy];// copy,mutableCopy二选一
       copy.age = self.age;
       return copy;
    }
    
    - (void)encodeWithCoder:(NSCoder *)aCoder{
    
        [aCoder encodeObject:self.name forKey:@"name"];
        [aCoder encodeInteger:self.age forKey:@"age"];
    }
    
    - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
    
        _name = [aDecoder decodeObjectForKey:@"name"];
        _age = [aDecoder decodeIntegerForKey:@"age"];
        return self;
    }
    
    @end
    
    
    @implementation Worker
     
    - (id)copyWithZone:(nullable NSZone *)zone{
     
        Worker *copy = [[[self class] allocWithZone:zone] init];
        copy.salary = [self.salary copy];
        copy.salary = [self.salary mutableCopy];// copy,mutableCopy二选一
        copy.leader = [self.leader copy];
        copy.leader = [self.leader mutableCopy];// 注意要实现NSMutableCopying; copy,mutableCopy二选一
        return copy;
    }
     
    - (void)encodeWithCoder:(NSCoder *)aCoder{
    
        [aCoder encodeObject:self.salary forKey:@"salary"];
        [aCoder encodeObject:self.leader forKey:@"leader"];
    }
    
    - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder{
    
        _salary = [aDecoder decodeObjectForKey:@"salary"];
        _leader = [aDecoder decodeObjectForKey:@"leader"];
        return self;
    }
    
    NSMutableArray *array = [[NSMutableArray alloc] init];
    Worker *worker = [[Worker alloc] init];
    worker.name = [NSString stringWithFormat:@"张三"];
    worker.age = 25;
    worker.salary = @"200";
    Person *leader = [[Person alloc] init];
    leader.name = [NSString stringWithFormat:@"领导"];
    leader.age = 30;
    worker.leader = leader;
    
    [array addObject:worker];
    
    // 不完全深拷贝
    NSArray *arrCopy = [array copy];
    NSMutableArray *arrMCopy = [array mutableCopy];
    Worker *worker1 = [array firstObject];
    Worker *wkrCopy = arrCopy.firstObject;
    Worker *wkrMCopy =arrMCopy.firstObject;
    wkrCopy.name = @"李四";
    wkrMCopy.name = @"王五";
    wkrCopy.leader.name = @"李四的领导";
    wkrMCopy.leader.name = @"王五的领导";
    
    NSLog(@"不完全深拷贝");
    NSLog(@"array= %p, person= %@, name= %@, leader= %p, %@, name= %@", array, worker1, worker1.name, worker1.leader, worker1.leader, worker1.leader.name);
    NSLog(@"arrCopy= %p, person= %@, name= %@, leader= %p, %@, name= %@", arrCopy, wkrCopy, wkrCopy.name, wkrCopy.leader, wkrCopy.leader, wkrCopy.leader.name);
    NSLog(@"arrMCopy= %p, person= %@, name= %@, leader= %p, %@, name= %@", arrMCopy, wkrMCopy, wkrMCopy.name, wkrMCopy.leader, wkrMCopy.leader, wkrMCopy.leader.name);
    
    //方式1 要在集合对象中实现NSCoding协议
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
    NSArray *array2 = [NSKeyedUnarchiver unarchiveTopLevelObjectWithData:data error:nil];
    
        
    //方式2 要在集合对象中实现NSCopying协议
    NSMutableArray *array3 = [[NSMutableArray alloc] initWithArray:array copyItems:YES];
    
    Worker *worker2 = [array2 firstObject];
    Worker *worker3 = [array3 firstObject];
    worker2.name = @"李四一";
    worker3.name = @"王五一";
    worker2.leader.name = @"李四一的领导";
    worker3.leader.name = @"王五一的领导";
    NSLog(@"完全深拷贝");
    NSLog(@"array= %p, person= %@, name= %@, leader= %p, %@, name= %@", array, worker1, worker1.name, worker1.leader, worker1.leader, worker1.leader.name);
    NSLog(@"array2= %p, person= %@, name= %@, leader= %p, %@, name= %@", array2, worker2, worker2.name, worker2.leader, worker2.leader, worker2.leader.name);
    NSLog(@"array3= %p, person= %@, name= %@, leader= %p, %@, name= %@", array3, worker3, worker3.name, worker3.leader, worker3.leader, worker3.leader.name);
    
    /*
    2022-10-12 14:41:37.733737+0800 OC深浅拷贝[52457:290164] 不完全深拷贝
    2022-10-12 14:41:37.733809+0800 OC深浅拷贝[52457:290164] array= 0x10140a280, person= <Worker: 0x10140a630>, name= 王五, leader= 0x10140ac80, <Person: 0x10140ac80>, name= 王五的领导
    2022-10-12 14:41:37.733867+0800 OC深浅拷贝[52457:290164] arrCopy= 0x10140a6e0, person= <Worker: 0x10140a630>, name= 王五, leader= 0x10140ac80, <Person: 0x10140ac80>, name= 王五的领导
    2022-10-12 14:41:37.735200+0800 OC深浅拷贝[52457:290164] arrMCopy= 0x10140b070, person= <Worker: 0x10140a630>, name= 王五, leader= 0x10140ac80, <Person: 0x10140ac80>, name= 王五的领导
    2022-10-12 14:41:37.735675+0800 OC深浅拷贝[52457:290164] 完全深拷贝
    2022-10-12 14:41:37.735798+0800 OC深浅拷贝[52457:290164] array= 0x10140a280, person= <Worker: 0x10140a630>, name= 王五, leader= 0x10140ac80, <Person: 0x10140ac80>, name= 王五的领导
    2022-10-12 14:41:37.735899+0800 OC深浅拷贝[52457:290164] array2= 0x101039ad0, person= <Worker: 0x10103a650>, name= 李四一, leader= 0x101038fe0, <Person: 0x101038fe0>, name= 李四一的领导
    2022-10-12 14:41:37.735977+0800 OC深浅拷贝[52457:290164] array3= 0x101608210, person= <Worker: 0x101039b80>, name= 王五一, leader= 0x101605d60, <Person: 0x101605d60>, name= 王五一的领导
    **/
    

    相关文章

      网友评论

          本文标题:Objective-C 浅拷贝、深拷贝、完全拷贝

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