-
【自定义类实现对象的拷贝 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