Reputation: 915
Say I have this:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
dict[@1] = @2;
dict[@3] = dict;
I archive dict
by calling:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:dict];
then I unarchive later:
NSMutableDictionary *dict2 = [NSKeyedUnarchiver unarchiveObjectWithData:data]
The problem is that dict2[@3]
is not dict2
, but rather an uninitialized NSDictionary
, and I was not able to recover what I had put in. Does anyone know how I would work around this? Thanks in advance!
Upvotes: 2
Views: 134
Reputation: 539745
It is explained by an Apple engineer on the Apple Mailing List: http://lists.apple.com/archives/cocoa-dev/2007/May/msg00747.html,
in reply to a similar question about archiving an NSMutableArray
containing itself as an element.
Summary:
This (very probably -- I haven't looked into it) is not a problem with the recursion per-se, but rather with objects which replace themselves during unarchiving by returning a new object from
initWithCoder:
.
...
So the summary answer is: you can't reliably have recursive references. In practice, though, these do occur (think of theNSView
subview/superview relationship) and things squeak by. Sometimes they don't and it's impossible to know beforehand if something will work or not.Chris Kane
Cocoa Frameworks, Apple
Upvotes: 4
Reputation: 5312
I would be really surprised if this worked. When you set dict[@3]=dict, you are basically giving it an infinite loop to create an infinitely deep dictionary. When you create data from the dictionary, it seems to protect you from that by replacing the infinite dictionary with an uninitialized one so that the user's ram is not completely drained before the application crashes.
If you were to try to print out dict[@3] in the console, the application would infinitely loop trying to print it out and would get stuck until it finally crashes sometime later.
Hence, f you want to store your dictionary in a dictionary, create another one.
Upvotes: 1