关于Copy
指针复制
- (void)viewDidLoad {
[super viewDidLoad];
/*
指针复制,p1和p2的地址相同
*/
RAPPerson *p1 = [RAPPerson new];
RAPPerson *p2 = p1;
NSLog(@"p1: %p---p2: %p", p1, p2);
}
对象复制
The exact meaning of “copy” can vary from class to class, but a copy must be a functionally independent object with values identical to the original at the time the copy was made.
- 待复制的类必须遵守
NSCopying
协议,具体的复制细节取决于其对于copyWithZone:
方法的实现。 - 根据文档描述,复制出的对象,其值和原始对象相同,但功能上
完全独立
的对象。 - 对于某些类,例如
NSString
,NSArray
,copy并不总是意味着创建新的对象。系统会出于优化内存
的目的,结合实际情况判断是否应该创建新的对象
,或返回原本的对象
。(具体出自哪个资料我忘记了,待查)
- (void)viewDidLoad {
[super viewDidLoad];
/*
对象复制,p1和p2地址不同
*/
RAPPerson *p1 = [RAPPerson new];
p1.age = 100;
RAPPerson *p2 = [p1 copy];
NSLog(@"%d", p2.age);
NSLog(@"p1: %p---p2: %p", p1, p2);
}
// 下面是RAPPerson类对于NSCopying协议的实现,及其定义的属性
@interface RAPPerson : NSObject <NSCopying>
/** 年龄 */
@property (nonatomic, assign) int age;
/** 朋友 */
@property (nonatomic, strong) NSArray *friends;
@end
@implementation RAPPerson
- (id)copyWithZone:(NSZone *)zone {
RAPPerson *copy = [[RAPPerson allocWithZone:zone] init];
copy.age = _age;
copy.friends = _friends
return copy;
}
@end
深层复制
- 根据
Effective Objective-C 2.0
书中Item 22
的描述,对象复制
其实是浅层复制
,即只复制了对象,但对象所携带的数据
,即属性,没有得到复制。 - 深层复制意味着
不仅复制对象
,而且复制对象的属性所指向的对象
。 - 不管是
NSCopying
还是NSMutableCopying
协议,都属于浅复制;想要实现深层复制,必须手动重写copyWithZone:
方法。
@implementation RAPPerson
- (id)copyWithZone:(NSZone *)zone {
RAPPerson *copy = [[RAPPerson allocWithZone:zone] init];
copy.age = _age;
// 不仅复制对象,还复制friends这个数组中所包含的所有对象
copy.friends = [[NSArray alloc] initWithArray:_friends copyItems:YES];
return copy;
}
@end