我有一个代表结构的类。
此类称为Object
具有以下属性
@property (nonatomic, strong) NSArray *children;
@property (nonatomic, assign) NSInteger type;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, weak) id parent;
children
是其他Object
s 的数组。parent
是对对象父对象的弱引用。
我正在尝试复制并粘贴此结构的一个分支。如果选择了根对象,parent
则显然是 nil。如果对象不是根,它有一个父对象。
为了能够做到这一点,种类的对象Object
必须符合NSCopying
和NSCoding
协议。
这是我在该类上的这些协议的实现。
-(id) copyWithZone: (NSZone *) zone
{
Object *obj = [[Object allocWithZone:zone] init];
if (obj) {
[obj setChildren:_children];
[obj setType:_type];
[obj setName:_name];
[obj setParent:_parent];
}
return obj;
}
- (void)encodeWithCoder:(NSCoder *)coder {
[coder encodeObject:@(self.type) forKey:@"type"];
[coder encodeObject:self.name forKey:@"name"];
NSData *childrenData = [NSKeyedArchiver archivedDataWithRootObject:self.children];
[coder encodeObject:childrenData forKey:@"children"];
[coder encodeConditionalObject:self.parent forKey:@"parent"]; //*
}
- (id)initWithCoder:(NSCoder *)coder {
self = [super init];
if (self) {
_type = [[coder decodeObjectForKey:@"type"] integerValue];
_name = [coder decodeObjectForKey:@"name"];
_parent = [coder decodeObjectForKey:@"parent"]; //*
NSData *childrenData = [coder decodeObjectForKey:@"children"];
_children = [NSKeyedUnarchiver unarchiveObjectWithData:childrenData];
_parent = nil;
}
return self;
}
您可能已经注意到,我没有参考检索或存储self.parent
,initWithCoder:
因此encodeWithCoder:
,对象的每个子对象都带有 parent = nil。
我只是不知道如何存储它。仅仅因为这个。假设我有这个结构Object
。
ObjectA > ObjectB > ObjectC
当encoderWithCoder:
启动它的魔法编码ObjectA
时,它也会进行编码,ObjectB
但是ObjectC
当它开始编码时,ObjectB
它会找到一个指向父引用的父引用ObjectA
并将再次启动它,创建一个挂起应用程序的循环引用。我试过了。
如何编码/恢复该父引用?
我需要的是存储一个对象,并在恢复时恢复一个与存储的相同的新副本。我不想恢复存储的同一个对象,而是一个副本。
注意:我已经//*
按照 Ken 的建议添加了标记的行,但是_parent
对于initWithCoder:
应该具有parent