码迷,mamicode.com
首页 > 其他好文 > 详细

copy 和 mutableCopy

时间:2015-03-11 23:22:35      阅读:224      评论:0      收藏:0      [点我收藏+]

标签:

retain 和 copy 的区别。

copy

copy是通过旧对象创建一个新对象,新对象引用计数器为1,与旧对象的引用计数无关。

retain

retain是创建一个指针,对象引用计数加1。retain 出来的指针和原对象的指针指向的内存地址是相同的。

如何实现copy

并不是所有对象都可以进行copy、mutableCopy 。对象如果可以被copy 则需要遵守NSCopying , 如果对象可以被mutableCopying 则需要遵从 NSMutableCopying。如果即可以被copy 也可以被mutableCopy 则需要同时遵守NSCopying 和 NSMutableCopying。

  • 遵守 NSCopying 需要实现 copyWithZone : 方法
  • 遵守 NSMutableCopying 需要实现 mutableCopyWithZone : 方法

值得注意的是一些API中的类已经遵守了NSCopying 协议或NSMutableCopying 协议,如NSArray等。

复制API中的对象

不可变对象的copy 是浅拷贝,这是拷贝源对象的指针,也就是retain.比如NSArray.
  1. NSArray *array = [NSArray array] ;
  2. // 对于不可变的对象copy只是浅拷贝,retain一下
  3. NSArray *arrayCopy = [array copy] ;
  4. // 通过输出得知两个对象的内存地址相同。
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;
可变对象的copy是创建出新的对象,开辟新的内存空间,真正意义上的复制,如 NSMutableArray.
  1. NSMutableArray *array = [NSMutableArray array] ;
  2. // 对于可变的对象copy是深拷贝,开辟内存空间
  3. NSArray *arrayCopy = [array copy] ;
  4. // 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;

mutableCopy

针对不可变对象的mutableCopy,会进行深拷贝,开辟新的内存空间
  1. NSArray *array = [NSArray array] ;
  2. // 对于不可变对象的可变拷贝, 深拷贝,开辟内存空间
  3. NSMutableArray *arrayCopy = [array mutableCopy] ;
  4. // 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;

关于数组元素的拷贝

当我们深拷贝数组的时候,数组的元素是浅拷贝。

  1. //将一个可变字符串填充到数组
  2. NSMutableArray * arr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithFormat:@"张三"] , nil];
  3. // 进行数组的copy
  4. NSMutableArray *arrayCopy = [arr copy];
  5. // 获得arr 的第一个元素
  6. NSMutableString *string = [arr objectAtIndex:0];
  7. // 修改第一个元素
  8. [string appendString:@"是个孩子"] ;
  9. // 输出拷贝数组的第一个元素,证明数组元素是浅拷贝.
  10. NSLog([arrayCopy objectAtIndex:0]) ; // 输出张三是个孩子.
如何对数组元素进行彻底的深拷贝?

使用归档技术,这种计数我们在归档的文章中详细讲解.

自定义对象如何copy ?

自定义对象想要被拷贝需要实现NSCopying、NSMutableCopying 。

  1. // Person 类
  2. @interface Person : NSObject <NSCopying,NSMutableCopying>
  3. @property NSObject *obj ;
  4. @end
copy : copyWithZone 方法。
  1. // 响应copy
  2. -(id) copyWithZone:(NSZone *)zone{
  3. // 初始化对象
  4. Person *p = [[[self class] allocWithZone:zone] init];
  5. // 属性拷贝
  6. p.obj = obj ;
  7. // 返回对象
  8. return p ;
  9. }
mutableCopy : mutableCopyWithZone 方法。
  1. // 响应mutableCopy
  2. -(id) mutableCopyWithZone:(NSZone *)zone{
  3. // 初始化对象
  4. Person *p = [[[self class] allocWithZone:zone] init];
  5. // 属性拷贝
  6. p.obj = obj ;
  7. // 返回对象
  8. return p ;
  9. }
关于代码中的[self class] allocWithZone

这是为了便于扩展性,当类被继承的时候,copyWithZone 等相关代码也会继承,这个时候使用 [self class] allocWithZone 可以更具有扩展性。

copy 和 继承

父类的copyWithZone
  1. // 父类的copy 响应方法
  2. -(id) copyWithZone:(NSZone *)zone{
  3. Person *person = [[[self class ] allocWithZone:zone]init];
  4. person.age = age;
  5. person.name = name;
  6. person.address = address ;
  7. return person ;
  8. }
子类的copyWithZone
  1. // 子类的copy 响应方法
  2. -(id) copyWithZone:(NSZone *)zone{
  3. // 先调用父类,让父类copyWithZone copy完父类属性
  4. Child *child = [super copyWithZone:zone] ;
  5. // copy子类属性
  6. child.childName = childName ;
  7. // 返回指针
  8. return child ;
  9. }

copy 和 mutableCopy

标签:

原文地址:http://www.cnblogs.com/mrwu/p/4331174.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!