如何在Objective-C中制作深层副本?

Fan*_*asy 22 objective-c deep-copy

我现在正在学习ios的开发,我对深层复制感到困惑.例如,我下面有三节课.现在我想深入复制ClassA,有人可以教我完成复制方法吗?

A:

@interface ClassA : NSObject <NSCopying>

@property (nonatomic, assign) int aInt;
@property (nonatomic, retain) ClassB *bClass;

@end
Run Code Online (Sandbox Code Playgroud)

B:

@interface ClassB : NSObject <NSCopying>

@property (nonatomic, assign) int bInt;
@property (nonatomic, retain) ClassC *cClass;

@end
Run Code Online (Sandbox Code Playgroud)

C:

@interface ClassC : NSObject <NSCopying>

@property (nonatomic, assign) int cInt;
@property (nonatomic, copy) NSString *str;

@end
Run Code Online (Sandbox Code Playgroud)

coh*_*n72 20

按照http://www.techotopia.com/index.php/Copying_Objects_in_Objective-C的说明进行操作

"这可以通过将对象及其组成元素写入存档然后读回新对象来实现."

@implementation ClassA

- (id)copyWithZone:(NSZone*)zone{
    NSData *buffer;
    buffer = [NSKeyedArchiver archivedDataWithRootObject:self];
    ClassA *copy = [NSKeyedUnarchiver unarchiveObjectWithData: buffer];
    return copy;
}
@end
Run Code Online (Sandbox Code Playgroud)

  • ClassA 中的所有自定义对象都必须实现 NSCoding 协议吗? (2认同)

Jam*_*ter 13

您应该copyWithZone:在要复制的每个类中添加该方法.

NB:我手写这个,小心打字错误.

-(id) copyWithZone:(NSZone *) zone
{
    ClassA *object = [super copyWithZone:zone];
    object.aInt = self.aInt;
    object.bClass = [self.bClass copyWithZone:zone];
    return object;
}

-(id) copyWithZone:(NSZone *) zone
{
    ClassB *object = [super copyWithZone:zone];
    object.bInt = self.bInt;
    object.cClass = [self.cClass copyWithZone:zone];
    return object;
}

-(id) copyWithZone:(NSZone *) zone
{
    ClassC *object = [super copyWithZone:zone];
    object.cInt = self.cInt;
    object.str = [self.str copy];
    return object;
}
Run Code Online (Sandbox Code Playgroud)


zou*_*oul 11

iOS上的Objective-C不提供任何直接语言或库构造来在浅拷贝和深拷贝之间切换.每个类定义"获取其副本"的含义:

@implementation ClassA

- (id) copyWithZone: (NSZone*) zone
{
    ClassA *copy = [super copyWithZone:zone];
    [copy setBClass:bClass]; // this would be a shallow copy
    [copy setBClass:[bClass copy]]; // this would be a deep copy
    return copy;
}

@end
Run Code Online (Sandbox Code Playgroud)

当然,你必须在ClassB和ClassC中做同样的决定.如果我没有弄错,Objective-C中副本的通常语义是返回浅表副本.另请参阅有关复制数组的问题,以获取有关该主题的更多讨论.