标签:
copy是通过旧对象创建一个新对象,新对象引用计数器为1,与旧对象的引用计数无关。
retain是创建一个指针,对象引用计数加1。retain 出来的指针和原对象的指针指向的内存地址是相同的。
并不是所有对象都可以进行copy、mutableCopy 。对象如果可以被copy 则需要遵守NSCopying , 如果对象可以被mutableCopying 则需要遵从 NSMutableCopying。如果即可以被copy 也可以被mutableCopy 则需要同时遵守NSCopying 和 NSMutableCopying。
值得注意的是一些API中的类已经遵守了NSCopying 协议或NSMutableCopying 协议,如NSArray等。
NSArray *array = [NSArray array] ;
// 对于不可变的对象copy只是浅拷贝,retain一下
NSArray *arrayCopy = [array copy] ;
// 通过输出得知两个对象的内存地址相同。
NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;
NSMutableArray *array = [NSMutableArray array] ;
// 对于可变的对象copy是深拷贝,开辟内存空间
NSArray *arrayCopy = [array copy] ;
// 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;
NSArray *array = [NSArray array] ;
// 对于不可变对象的可变拷贝, 深拷贝,开辟内存空间
NSMutableArray *arrayCopy = [array mutableCopy] ;
// 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;
当我们深拷贝数组的时候,数组的元素是浅拷贝。
//将一个可变字符串填充到数组
NSMutableArray * arr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithFormat:@"张三"] , nil];
// 进行数组的copy
NSMutableArray *arrayCopy = [arr copy];
// 获得arr 的第一个元素
NSMutableString *string = [arr objectAtIndex:0];
// 修改第一个元素
[string appendString:@"是个孩子"] ;
// 输出拷贝数组的第一个元素,证明数组元素是浅拷贝.
NSLog([arrayCopy objectAtIndex:0]) ; // 输出张三是个孩子.
使用归档技术,这种计数我们在归档的文章中详细讲解.
自定义对象想要被拷贝需要实现NSCopying、NSMutableCopying 。
// Person 类
@interface Person : NSObject <NSCopying,NSMutableCopying>
@property NSObject *obj ;
@end
// 响应copy
-(id) copyWithZone:(NSZone *)zone{
// 初始化对象
Person *p = [[[self class] allocWithZone:zone] init];
// 属性拷贝
p.obj = obj ;
// 返回对象
return p ;
}
// 响应mutableCopy
-(id) mutableCopyWithZone:(NSZone *)zone{
// 初始化对象
Person *p = [[[self class] allocWithZone:zone] init];
// 属性拷贝
p.obj = obj ;
// 返回对象
return p ;
}
这是为了便于扩展性,当类被继承的时候,copyWithZone 等相关代码也会继承,这个时候使用 [self class] allocWithZone 可以更具有扩展性。
// 父类的copy 响应方法
-(id) copyWithZone:(NSZone *)zone{
Person *person = [[[self class ] allocWithZone:zone]init];
person.age = age;
person.name = name;
person.address = address ;
return person ;
}
// 子类的copy 响应方法
-(id) copyWithZone:(NSZone *)zone{
// 先调用父类,让父类copyWithZone copy完父类属性
Child *child = [super copyWithZone:zone] ;
// copy子类属性
child.childName = childName ;
// 返回指针
return child ;
}
标签:
原文地址:http://www.cnblogs.com/mrwu/p/4331174.html