文档章节

copy 自定义对象

 王素年
发布于 2017/07/12 11:10
字数 846
阅读 3
收藏 0
点赞 0
评论 0

要向让我们自己创建的对象调用copy 方法,( [p copy] ) 前提条件是:

1>  遵守NSCopying协议  (本质上就是方便程序员编写代码时候,有快捷提示) 
2> 实现 - (id)copyWithZone:(NSZone *)zone

     copy方法,      最终都会调用copyWithZone方法

mutablecopy方法,最终都会调用mutableCopyWithZone方法

 

有一个模型对象Person

@interface Person : NSObject<NSCopying,NSMutableCopying>

@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;

@end

 

遵守NSCopying协议 ,重写Person 的 copyWithZone方法 和 mutableCopyWithZone     copy操作一个对象,复制给一个新的对象。

- (id)copyWithZone:(NSZone *)zone
{
    // 1> 实例化对象,self 是对象
    // self.class能够保证继承的子类同样使用copy方法
    Person *p = [[self.class alloc] init];
    //Person * p = [[self.class allocWithZone:zone] init];

    // 2> 给属性赋值,深拷贝一份属性[self.name copy]字符串的copy方法,赋给新对象,但是这里不需要因为属性是不可变字符串。
    p.name = self.name;
    p.age = self.age;

    // 3> 返回新对象
    return p;
}

 

验证: 

- (void)viewDidLoad {
    [super viewDidLoad];


    Person *p = [Person new];

    Person *p2 = [p copy];

    
    NSLog(@"%@,%@", p, p2);

}

 结果如下:两个对象地址不一样。哦了

 

 

 

上面的模型属性中不包含容器类对象,如果包含容器类对象,我们这样写的话,会导致容器本身是深拷贝了,但是容器里面盛放的对象并不是深拷贝。里面的对象依旧是浅拷贝。面对这种情况应该这样写:

有一个Person模型对象,其中有一个 NSArray属性 

@interface Person : NSObject<NSCopying,NSMutableCopying>

@property(nonatomic,copy)NSString *name;
@property(nonatomic,assign)NSInteger age;
@property(nonatomic,strong)NSArray *arr;

@end

重写 Person 的 copyWithZone方法 和 mutableCopyWithZone 注意:p.arr = 不能简单的赋值,需要调用initWithArray:  copyItems: 方法,这个方法可以让数组实现深拷贝,但是仅限于数组中没有再嵌套容器类,如果数组中再嵌套容器类,这个方法就不行了,需要使用归档。

- (id)copyWithZone:(NSZone *)zone{
    
    //实例化对象
    //self.class能够保证继承的子类可以使用copy方法
    Person * p = [[self.class alloc] init];
    
    //给属性赋值
    p.age = self.age;
    p.name = self.name;

//这里要注意了,不能单纯的赋值,单纯的赋值,就是代表引用同一个数组,当一个数组中的元素改变了。copy的数组中也会改,所以要深copy一份数组
    p.arr = [[NSArray alloc] initWithArray:self.arr copyItems:YES];
    
    //返回新对象
    return p;
    
}

 

另外需要注意:initWithArray: copyItem: 这个方法调用时,self.arr中的对象 必须要具有copy的能力,不然会崩溃的,所以我们要将数组中的元素实现copy的方法。

- (id)copyWithZone:(NSZone *)zone{
    
    //实例化对象
    //self.class能够保证继承的子类可以使用copy方法
    pm * p = [[self.class alloc] init];
    
    //给属性赋值
    p.days = self.days;
    
    //返回新对象
    return p;
    
}


- (id)mutableCopyWithZone:(NSZone *)zone{
    
    //实例化对象
    //self.class能够保证继承的子类可以使用copy方法
    pm * p = [[self.class alloc] init];
    
    //给属性赋值
    p.days = self.days;
    
    //返回新对象
    return p;
    
}

 

验证:

//创建数组
    pm *pmm = [pm new];
    pmm.days = @"one";
    NSArray *array = [NSArray arrayWithObjects:pmm, nil];
    

    //创建模型
    Person *p = [Person new];
    //给模型中的数组赋值
    p.arr = array;
    
    
    
    //copy模型
    Person *p2 = [p copy];
    //修改copy后的模型数组中对象的值
    [[p2.arr lastObject] setDays:@"two"] ;
    
    //打印结果
    NSLog(@"%@", [[p.arr lastObject] days]);
    NSLog(@"%@", [[p2.arr lastObject] days]);

结果如下:修改copy后的对象中的数组属性中的元素后, 原始的对象中的值并没有变,说明copy成功了。

 

 

© 著作权归作者所有

共有 人打赏支持
粉丝 2
博文 70
码字总数 43954
作品 0
普陀
程序员
沙盒存储

l每个iOS应用都有自己的应用沙盒(应用沙盒就是应用的文件夹),与其他文件系统隔离。应用必须待在自己的沙盒里,其他应用不能访问该沙盒.但是,再iOS8之后通过某些操作是可以访问的 l应用沙盒的...

奋斗的青春年华
2016/08/15
3
0
Objective-C浅拷贝和深拷贝

浅拷贝 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。如: char str = (char)malloc(100); char* str2 = str; 浅拷贝只是对对象的简单拷贝,让几个对象共用一片内...

大喵哥
2014/09/20
0
0
Java的深拷贝和浅拷贝

熟悉C++的朋友对这个话题应该很熟悉,浅拷贝就是指两个对象共同拥有同一个值,一个对象改变了该值,也会影响到另一个对象。深拷贝就是两个对象的值相等,但是互相独立。本来想把以前写的一篇...

长平狐
2012/08/28
84
0
IOS开发之深拷贝与浅拷贝(mutableCopy与Copy)详解

阅读本文之前首先了解copy与retain的区别,如果有不正确的地方望大家多多指教: copy与retain的区别: copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内...

木木情深
2014/02/19
0
0
构造函数的理解和应用场景

最近对C++的构造函数做了一个小小的总结,说是C++,其实java等面向对象高级语言对构造函数处理的本质都是一样的,只不过是有些许语法的区别罢了。 1、 为什么需要构造函数? 当我们在创建一个...

沙米笔记
2016/03/30
598
1
Objective-C深复制和协议

1.简单复制只能实现浅拷贝:指针赋值,使两个指针指向相同的一块内存空间,操作不安全。 2. Foundation类已经遵守了<NSCopying>和 <NSMutableCopying>协议,即实现了copy和mutableCopy方法,因...

雾灵峰
2014/02/04
0
0
Flex4自定义事件类型Event的相关应用

基于松耦合的概念 自定义事件类型将取到很重要的作用 当您创建自己的自定义 Event 类时,必须覆盖继承的 Event.clone() 方法,以复制自定义类的属性。如果您未设置在事件子类中添加的所有属性...

leesama
2013/08/14
0
0
JS中dataTransfer对象在拖曳操作中的妙用。

dataTransfer对象提供了对于预定义的剪贴板格式的访问,以便在拖曳操作中使用。 通俗的讲就是在拖曳操作的过程中,我们可以用过dataTransfer对象来传输数据,以便在拖曳操作结束的时候对数据...

Jialy
2013/11/26
0
0
iOS archive(归档)的总结

iOS 归档的记录 归档是一种很常用的文件储存方法,几乎任何类型的对象都能够被归档储存(实际上是一种文件保存的形式),浏览网上的一些资料后,并结合自己的一些经验,总结成此文。 一、使用...

今日竹石
2014/01/23
0
0
iOS开发——深拷贝与浅拷贝详解

深拷贝和浅拷贝这个问题在面试中常常被问到,而在实际开发中,只要稍有不慎,就会在这里出现问题。尤其对于初学者来说,我们有必要来好好研究下这个概念。我会以实际代码来演示,相关示例代码...

CHENYUFENG1991
2016/06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

大数据教程(2.11):keeperalived+nginx高可用集群搭建教程

上一章节博主为大家介绍了目前大型互联网项目的系统架构体系,相信大家应该注意到其中很重要的一块知识nginx技术,在本节博主将为大家分享nginx的相关技术以及配置过程。 一、nginx相关概念 ...

em_aaron
4分钟前
0
0
Apache Directory Studio连接Weblogic内置LDAP

OBIEE默认使用Weblogic内置LDAP管理用户及组。 要整理已存在的用户及组,此前办法是导出安全数据,文本编辑器打开认证文件,使用正则表达式获取用户及组的信息。 后来想到直接用Apache Dire...

wffger
11分钟前
0
0
HFS

FS,它是一种上传文件的软件。 专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,...

garkey
15分钟前
0
0
STM 32 窗口看门狗

http://bbs.elecfans.com/jishu_805708_1_1.html https://blog.csdn.net/a1985831055/article/details/77404131...

whoisliang
昨天
0
0
Dubbo解析(六)-服务调用

当dubbo消费方和提供方都发布和引用完成后,第四步就是消费方调用提供方。 还是以dubbo的DemoService举例 -- 提供方<dubbo:application name="demo-provider"/><dubbo:registry address="z...

青离
昨天
1
0
iptables规则备份和恢复、firewalld的9个zone以及操作和service的操作

保存以及备份iptalbes规则 设定了的防火墙规则要进行保存,否则系统重启后这些规则就没有了,使用命令 ”service iptables save ” 会把设定好的防火墙规则保存到文件/etc/sysconfig/iptabl...

黄昏残影
昨天
0
0
k8s image

k8s.gcr.io/kube-apiserver-amd64:v1.11.0k8s.gcr.io/kube-controller-manager-amd64:v1.11.0k8s.gcr.io/kube-scheduler-amd64:v1.11.0k8s.gcr.io/kube-proxy-amd64:v1.11.0k8s.gcr.......

分秒
昨天
0
0
数据结构--排序

这篇博客包含了数据结构中多种的排序算法: (1)简单选择:第一趟在A[0]~A[n-1]之间找到最小的,与A[0]进行交换,之后在A[1]~A[n-1]之间进行。。。第i趟在A[i-1]~A[n-1]之间找到最小的,最后...

wangxuwei
昨天
1
0
一名3年工作经验的java程序员应该具备的职业技能

一名3年工作经验的Java程序员应该具备的技能,这可能是Java程序员们比较关心的内容。我这里要说明一下,以下列举的内容不是都要会的东西—-但是如果你掌握得越多,最终能得到的评价、拿到的薪...

老道士
昨天
3
0
MAC安装JDK

一 :在JDK官网下载对应的JDK版本 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 二:找到JDK安装目录,点击会出现图标,双击图标自动安装,勾选默...

WALK_MAN
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部