• 【自定义类实现对象的拷贝 Objective-C语言】


    一、我们上一小节,说过,copy是个方法,对吧,它是定义在我们这个NSObject类中的方法,那么言下之意,就是说,我们所有的类,是不是都应该有这个copy方法啊,

    1.比如,我这儿有一个Person类,

    这个Person类里面呢,我给它来个姓名吧

    在Person.h文件中

    import

    @interface Person:NSObject

    @property(nonatomic,copy)NSString *name;

    //再来1个年龄吧

    @property(nonatomic,assign)int age;

    @end

    在main.m文件中

    #import

    #import “Person.h”

    int main(){

    Person *p1 = [Person new];

    //猜1下,里面有没有copy方法,p1对象,有

    //[p1 copy];

    //这个方法的签名如下:

    //id copy

    //这个时候,它是不是就copy1个对象出来啊,深拷贝还是浅拷贝呢

    Person *p2 = [p1 copy];

    //我们是不是去试一下啊

    return 0;

    }

    走一个,报错了,这句话

    Person *p2 = [p1 copy];

    它说这个方法是不是无法识别啊

    2.copy方法的确是定义在NSObject类中的1个方法

    NSObject里面的copy方法,它还调用了另一个方法

    copy方法的内部,调用了另外1个方法,叫做copyWithZone

    这个方法,它是什么方法呢,这个方法是定义在NSCopying协议之中的

    我们看一下啊,

    Person< NSCopying> *p2 = [p1 copy];

    在这句话里点NSCopying,跳转到定义

    这个NSCopying协议的签名如下:

    @protocol NSCopying

    - (id)copyWithZone:(nullable NSZone *)zone;

    @end

    这个协议就1个方法,

    叫copyWithZone

    对不对,言下之意,就是说,我们这个NSObject类里面的copy方法,其实调用的copyWithZone方法,

    所以,我这个Person对象,有遵守这个NSCopying协议吗,没有

    我这个Person对象里面,有那个copyWithZone方法吗,没有

    所以我一调用copy方法,它就报错,

    因为copy方法的内部,它会调用什么啊,它会调用copyWithZone方法

    3.因为我们的类没有遵守NSCopying协议,那么我们的类中就没有copyWithZone这个方法,

    所以,当我们自定义的类,调用copy方法的时候,就会出错

    二、如果我们想要让我们自己的类具备对象拷贝的能力,那么就让我们的类遵守NSCopying协议,并实现copyWithZone这个方法,

    1.好了,那我们实现一下啊,遵守一下啊

    在Person.h文件中

    #import

    @interface Person:NSObject < NSCopying>

    @property(nonatomic,copy)NSString *name;

    @property(nonatomic,assign)int age;

    @end

    然后这个协议里面就1个方法吧

    好,把这个方法实现一下啊

    在Person.m文件中

    #import “Person.h”

    @implementation Person

    - (id)copyWithZone:(NSZone *)zone{

    //记住,我再强调一遍啊,copy方法的内部,就会调用这个方法

    //1.这个方法怎么实现

    //如何实现,就是要看你是想要做深拷贝,还是浅拷贝

    //如果要做深拷贝,你就重新创建1个对象,把当前对象的属性的值,复制到新对象里面去啊,将新对象返回,你可以这么做啊

    Person *p1 = [Person new];

    p1.name = _name;

    p1.age = _age;

    return p1;

    //是不是重新创建1个新对象啊,

    //然后呢,把当前这个对象的name和age的值,复制给了这个p1对象的属性啊

    //最后,return p1

    }

    这个时候,我再去拷贝

    Person *p2 = [p1 copy];

    这个时候,我再去调用p1对象的copy方法,它还会报错吗,就不会了

    但这个时候,我copy,是深拷贝还是浅拷贝呢,深拷贝

    我试一下啊,在main.m文件中

    #import

    #import “Person.h”

    int main(){

    Person *p1 = [Person new];

    Person *p2 = [p1 copy];

    NSLog(@“p1 = %p”,p1);

    NSLog(@“p2 = %p”,p2);

    }

    输出:p1 = 0x101536520

    p2 = 0x101536580

    看到了吗,这个时候,它出来的是两个完全不同的对象

    但是,有1个问题啊,我如果给p1.name赋1个@“jack”

    p1.name = @“jack”;

    p1.age = 18;

    在main.m文件中

    #import

    #import “Person.h”

    int main(){

    Person *p1 = [Person new];

    p1.name = @“jack”;

    p1.age = 18;

    Person *p2 = [p1 copy];

    NSLog(@“p1 = %p”,p1);

    NSLog(@“p2 = %p”,p2);

    }

    但是这个时候,p2.name是什么,@“jack”,p2.age是什么,18

    因为我copy的时候,是不是复制的这个对象的属性值啊,

    这就是深拷贝,

    三、我想让它浅拷贝呢

    1.如果你想浅拷贝,就更简单了

    在Person.m文件中

    #import “Person.h”

    @implementation Person

    - (id)copyWithZone:(NSZone *)zone

    {

    return self;

    }

    @end

    对,return self,直接就返回当前这个对象的地址,就可以了

    这个时候你再看啊,是什么拷贝呢

    在main.m文件中

    #import

    #import “Person.h”

    int main(){

    Person *p1 = [Person new];

    Person *p2 = [p1 copy];

    NSLog(@“p1 = %p”,p1);

    NSLog(@“p2 = %p”,p2);

    }

    输出:p1 = 0x10121b0a0

    p2 = 0x10121b0a0

    有没有新创建对象啊,没有

    四、所以,如果说,你自己的类啊,想要拥有对象拷贝的行为,那么你就去遵守那个NSCopying协议,然后实现那个copyWithZone方法,

    怎么实现,看你自己的,如果你想拷贝的时候,是深拷贝,你就重新创建对象,然后呢,把当前对象的属性值,复制一下就可以了,

    如果你想浅拷贝,你就直接返回self的值,就可以了

    五、总结:

    如果想要实现深拷贝:那么就重新创建1个对象,并将对象的属性的值复制,返回

    如果想要实现浅拷贝:那么就直接返回self的值

    好了,以上就是自定义类实现对象的拷贝

  • 相关阅读:
    宠物寄养小程序实战教程02
    2019年[海淀区赛 第2题] 阶乘
    【预处理详解】
    B站7月榜单丨飞瓜数据B站UP主排行榜发布!
    Studio one 6.5中文直装版最新版,一键安装丨无套路分享丨宿主软件丨机架直播
    ChatGPT国内能用吗?中国用户怎么才能使用ChatGPT?
    华为ensp创建 VLAN
    1) 数字信号及其基本运算
    22071系统移植day5
    YOLOV5学习笔记(六)——优化网络架构
  • 原文地址:https://blog.csdn.net/madoca/article/details/128192957