copy 自定义对象
2017-07-12 00:00
120 查看
要向让我们自己创建的对象调用copy 方法,( [p copy] ) 前提条件是:
1> 遵守NSCopying协议 (本质上就是方便程序员编写代码时候,有快捷提示)
2> 实现 - (id)copyWithZone:(NSZone *)zone
copy方法, 最终都会调用copyWithZone方法
mutablecopy方法,最终都会调用mutableCopyWithZone方法
有一个模型对象Person
遵守NSCopying协议 ,重写Person 的 copyWithZone方法 和 mutableCopyWithZone copy操作一个对象,复制给一个新的对象。
验证:
结果如下:两个对象地址不一样。哦了
上面的模型属性中不包含容器类对象,如果包含容器类对象,我们这样写的话,会导致容器本身是深拷贝了,但是容器里面盛放的对象并不是深拷贝。里面的对象依旧是浅拷贝。面对这种情况应该这样写:
有一个Person模型对象,其中有一个 NSArray属性
重写 Person 的 copyWithZone方法 和 mutableCopyWithZone ,注意:p.arr = 不能简单的赋值,需要调用initWithArray: copyItems: 方法,这个方法可以让数组实现深拷贝,但是仅限于数组中没有再嵌套容器类,如果数组中再嵌套容器类,这个方法就不行了,需要使用归档。
另外需要注意:initWithArray: copyItem: 这个方法调用时,self.arr中的对象 必须要具有copy的能力,不然会崩溃的,所以我们要将数组中的元素实现copy的方法。
验证:
结果如下:修改copy后的对象中的数组属性中的元素后, 原始的对象中的值并没有变,说明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成功了。
相关文章推荐
- 猫猫整理问题之:copy,对象自定义copy
- (转载)copy,对象自定义copy 什么是property
- Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)
- AJ整理问题之:copy,对象自定义copy 什么是property
- 猫猫整理问题之:copy,对象自定义copy 什么是property
- Objective-C Copy语法(二)对于我们自定义对象Copy以及[self class]相关的错误
- 自定义对象的拷贝(copy 和 strong 的区别)
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- 关于WebService传递自定义对象的问题
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- 深入Atlas系列:Web Sevices Access in Atlas示例(2) - 自定义JavaScriptConverter处理循环引用对象
- 怎样调用动态获取的自定义对象的方法
- 与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable
- ADO.NET 2.0 - 读者询问能否使用 SqlBulkCopy 对象来大量复制文字文件
- 如何设计和使用自定义的权限对象(自定义权限检查函数)
- 访问使用自定义弹出对象的网页时,Internet Explorer 6 意外关闭
- VIsual Basic 2005 - 如何使用 SqlBulkCopy 对象来执行大量复制作业
- JS写自定义对象语法
- 与DotNet数据对象结合的自定义数据对象设计 (一) 数据对象与DataRow
- Javascript 自定义对象[转载]