Re: NSKeyedUnarchiver and "root" key
Re: NSKeyedUnarchiver and "root" key
- Subject: Re: NSKeyedUnarchiver and "root" key
- From: Chris Kane <email@hidden>
- Date: Mon, 12 Jan 2004 08:00:41 -0800
You should probably be subclassing NSKeyedArchiver and
NSKeyedUnarchiver both, as a pair, rather than just one or the other.
Then override +archivedDataWithRootObject: on NSKeyedArchiver and
+unarchiveObjectWithData: NSKeyedUnarchiver if those are the methods
you want to use. Otherwise, add your own methods which take whatever
information you like. (And possibly provide your own init methods,
depending on what you're doing, and call the super classes'
initializers from your own.)
If you're just adding information to the top level of the archive,
containment could also be used: create an object which contains an
NSKeyedUnarchiver (and possibly the same for NSKeyedArchiver) as an
ivar, rather than subclassing.
It seems like doing the same thing for both the archiving and
unarchiving side is likely to produce a more symmetric design (and
probably better) than, say, just throwing some additional top-level
keys into a document on the archiving side, but using a object to wrap
that on the unarchiving side.
Chris Kane
Cocoa Frameworks, Apple
On Dec 30, 2003, at 6:00 PM, Manfred Lippert wrote:
Hi,
I tried to subclass NSKeyedUnarchiver because I want to add some
instance variables, e.g. a "document version".
There is no chance to extend the class by overriding
"unarchiveObjectWithData" because this method is a class method (there
are no instance variables at this point). So I tried it with
"initForReadingWithData". I wrote a subclass of NSKeyedUnarchiver,
e.g. named MyUnarchiver, and added some method
"initForReadingWithData:myExtensions:..." where I can add some
parameters (e.g. document version) that are then stored as instance
variables in my MyArchiver object.
Then I replaced my previous decoding code:
myObject = [[NSKeyedUnarchiver unarchiveObjectWithData:data] retain];
with this new version:
MyUnarchiver *unarchiver = [[MyUnarchiver alloc]
initForReadingWithData:data myExtensions:...];
myObject = [[unarchiver decodeObject] retain];
[unarchiver release];
I did this a while ago with a normal NSArchiver (not keyed) and there
this works. But not this time with the keyed archiver. Every time I
got back a <null> object. After debugging a while, I found out that
the NSKeyedArchiver (that generates the archive) encodes the root
object as keyed object with a key named "root"! So I have to write
this:
MyUnarchiver *unarchiver = [[MyUnarchiver alloc]
initForReadingWithData:data myExtensions:...];
myObject = [[unarchiver decodeObjectForKey:@"root"] retain];
[unarchiver release];
This works like a charm. :-)
BUT: Is it somewhere documented, that the root object of keyed
archiver data has a key named "root"?!? Can I be sure Apple does not
change it sometime? I searched the documentation and could not find an
answer to this. I had to write a subclass of NSKeyedArchiver and
override "encodeObject:ForKey:" and print out the key names to find
out that the root key is named "root" ... not a very obvious. ;-) So
now I want to get sure that this is specified somewhere to be also
true for future Cocoa versions.
Or is there some better way to add some parameters (e.g. document
version) to NSKeyedUnarchiver?
The objects that implement the NSCoding protocol only gets references
to the NSCoder subclass (normally the used NSKeyedUnarchiver or own
subclass of it), so in my solution they can ask the NSCoder for the
parameters. Is this bad design? What's a better way?
Thanks,
Mani
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.