美文网首页
第22条:理解NSCopying协议

第22条:理解NSCopying协议

作者: MrSYLong | 来源:发表于2018-09-23 15:37 被阅读10次

    使某个类支持拷贝功能,只需声明该类遵从NSCopying协议,并且实现copyWithZone方法即可。

    - (id)copyWithZone:(NSZone *)zone
    注意:
    为何需要NSZone?
    以前开发程序,会把内存分成不同的“区”(zone),而对象会创建在某个区里。
    现在不用了,一个程序只有一个区:“默认区”(default zone)。
    不必在担心其中的zone参数。
    
    // 头文件:
    #import <Foundation/Foundation.h>
    
    @interface EOCPerson : NSObject <NSCopying>
    
    @property (nonatomic, copy, readonly) NSString *firstName;
    @property (nonatomic, copy, readonly) NSString *lastName;
    
    - (id)initWithFirstName:(NSString *)firstName
                andLastName:(NSString *)lastName;
    
    - (void)addFriend:(EOCPerson *)person;
    - (void)removeFriend:(EOCPerson *)person;
    
    @end
    
    // 实现文件:
    #import "EOCPerson.h"
    
    @implementation EOCPerson {
        NSMutableSet *_friends;
    }
    
    - (id)initWithFirstName:(NSString *)firstName
                andLastName:(NSString *)lastName
    {
        if ((self = [super init])) {
            _firstName = [firstName copy];
            _lastName = [lastName copy];
            _friends = [NSMutableSet new];
        }
        return self;
    }
    
    - (void)addFriend:(EOCPerson *)person
    {
        [_friends addObject:person];
    }
    
    - (void)removeFriend:(EOCPerson *)person
    {
        [_friends removeObject:person];
    }
    
    - (id)copyWithZone:(NSZone *)zone
    {
        EOCPerson *copy = [[[self class] allocWithZone:zone]
                                     initWithFirstName:_firstName
                                           andLastName:_lastName];
        // 使用->语法:friends不是属性,只是一个实例变量
        // _friends是一个可变set,不能共享,需要拷贝一份,如果是不可变的,那么是不需要拷贝的。
        copy->_friends = [_friends mutableCopy];
        return copy;
    }
    
    @end
    
    // 举例:
    EOCPerson *personA = [[EOCPerson alloc] initWithFirstName:@"Tom" andLastName:@"Too"];
    
    EOCPerson *personB = [[EOCPerson alloc] initWithFirstName:@"Mark" andLastName:@"Moo"];
    EOCPerson *personC = [[EOCPerson alloc] initWithFirstName:@"Yar" andLastName:@"Yoo"];
    
    [personA addFriend:personB];
    [personA addFriend:personC];
    
    EOCPerson *copyPersonA = [personA copy];
    

    通常情况,采用全能初始化方法来初始化拷贝的对象,但有时,会有一些“副作用”。

    如果自定义对象还有可变版本,那么需要遵从NSMutableCopying协议,并实现mutableCopyWithZone方法

    - (id)mutableCopyWithZone:(NSZone *)zone;
    

    浅拷贝:Foundation框架中所有collection类在默认情况下都是执行浅拷贝,只拷贝容器对象本身,而不复制其中的数据。

    深拷贝:在拷贝容器对象自身时,也将其底层数据一并复制一份过去。

    如果所写的对象需要深拷贝,那么可以考虑新增一个专门执行深拷贝的方法。


    浅拷贝与深拷贝对比图.jpg

    相关文章

      网友评论

          本文标题:第22条:理解NSCopying协议

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