lundi 2 mars 2015

Copying and Pasting, Archiving and Unarchiving a structure

I have a class that represents a structure.


This class called Object has the following properties



@property (nonatomic, strong) NSArray *children;
@property (nonatomic, assign) NSInteger type;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, weak) id parent;


children is an array of other Objects. parent is a weak reference to an object parent.


I am trying to do copy and paste. To be able to do so, the objects of kind Object have to conform to NSCopying and NSCoding protocols.


This is my implementation of these protocols on that class.



-(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"];
}

- (id)initWithCoder:(NSCoder *)coder {

self = [super init];

if (self) {

_type = [[coder decodeObjectForKey:@"type"] integerValue];
_name = [coder decodeObjectForKey:@"name"];

NSData *childrenData = [coder decodeObjectForKey:@"children"];
_children = [NSKeyedUnarchiver unarchiveObjectWithData:childrenData];
_parent = nil;
}

return self;

}


You may have notice that I have no reference to retrieve or storing self.parent on initWithCoder: and encodeWithCoder: and because of that, every sub object of an object comes with parent = nil.


I simply don't know how to store that. Simply because of this. Suppose I have this structure of Object.



ObjectA > ObjectB > ObjectC


When encoderWithCoder: starts its magic encoding ObjectA, it will also encode, ObjectB and ObjectC but when it starts encoding ObjectB it finds a parent reference pointing to ObjectA and will start that again, creating a circular reference that hangs the application. I tried that.


How do I encode/restore that parent reference?


What I need is to store an object and by the time of restore, to restore a new copy, identical to what was stored. I don't want to restore the same object that was stored, but rather, a copy.




Aucun commentaire:

Enregistrer un commentaire