Re: NSArchiverArchiveInconsistency ???
Re: NSArchiverArchiveInconsistency ???
- Subject: Re: NSArchiverArchiveInconsistency ???
- From: "Louis C. Sacha" <email@hidden>
- Date: Wed, 18 Feb 2004 20:59:11 -0800
Hello...
I'm guessing that you haven't actually made the IBPallete yet, and
you are still adding instances of your class to the nib in
InterfaceBuilder by adding a NSTextField and then using "Custom
Class" in the inspector to choose your subclass...
The short answer:
You are running into a limitation of non-keyed coding. The easiest
way to fix this is to require and use keyed archiving (which also
requires your nibs to be in the current 10.2+ format).
/* assuming underlineWhenMouseIsOver is a BOOL */
/* this also assumes that the default value of FALSE is okay if keyed
archiving is not supported or there is no archived value for the key
*/
-------------------------
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
if ([coder allowsKeyedCoding])
{
[coder encodeBool:underlineWhenMouseIsOver
forKey:@"YourClassName underlineWhenMouseIsOver"];
}
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ( self = [super initWithCoder:decoder] )
{
if ([decoder allowsKeyedCoding])
{
underlineWhenMouseIsOver = [decoder
decodeBoolForKey:@"YourClassName underlineWhenMouseIsOver"];
}
}
return self;
}
-------------------------
The long answer:
(anyone out there with a link to the docs that talk about this, or
any corrections, please feel free to jump in...)
When you use "Custom Class" in InterfaceBuilder, the object that is
archived in the nib is _not_ an instance of your class, it is an
instance of whatever class is built into InterfaceBuilder or you
dragged from the pallete. In your case, that means that in
InterfaceBuilder you are working with an instance of NSTextField.
When the nib is saved, the object that is archived is the instance of
NSTextField, using the NSTextField encodeWithCoder: method, and your
version of the encodeWithCoder: method is never called. The name of
your custom class is also encoded, so that when the object is
unarchived, your class will be used.
When the nib is loaded, the unarchiver creates an instance of your
class, but the encoded data is encoded in the form used by
NSTextField, and doesn't contain the extra data that your override of
the encodeWithCoder: method would have added. So when you try to
decode it, that extra encoded data is not present, causing the
exception. This is a limitation in non-keyed archiving, since it
requires that all data be encoded and decoded in the same order, and
doesn't provide a simple way to avoid problems like you are having.
Keyed archiving solves those problems, and if you're not familiar
with it, there is basic info in the docs for NSCoder,
NSKeyedArchiver, and NSKeyedUnarchiver, and a more detailed
explanation in the Cocoa conceptual documentation under the topic
"Archiving and Serialization".
When you use keyed archiving, it doesn't matter if the data encoded
for the object is for NSTextField instead of from your class, since
you can easily just use a default value if the key is not present (or
if the default value of FALSE for a BOOL is okay, you don't need to
actually check if the key is in the archive or not).
Once you had made the pallete, it would partially fix this problem
since then the object used within InterfaceBuilder will be an actual
instance of your class when it is dragged from your pallete. If you
wanted to allow people to use your class without using the pallete,
the method where the header is imported and "Custom Class" would
still have the same problem you are currently having, so you would
probably want to fix it anyway to allow that option.
Hope that helps,
Louis
Hello Gurus,
I've been hitting on this problem for whole the day so I
decided to write you,
I sub-classed the NSTextField and I because I wanted to make it a
IBPalette added the method in order to support <NSCoding>
now when I run my application I get:
2004-02-18 21:56:42.688 FrameworkDebug[6831] An uncaught exception was raised
2004-02-18 21:56:42.717 FrameworkDebug[6831] *** Incorrect archive:
unexpected byte
2004-02-18 21:56:42.728 FrameworkDebug[6831] *** Uncaught exception:
<NSArchiverArchiveInconsistency> *** Incorrect archive: unexpected
byte
but I really can't see where the problem is since these are the 2 methods:
-------------------------
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder
encodeValueOfObjCType:@encode(typeof(underlineWhenMouseIsOver))
at:&underlineWhenMouseIsOver];
}
- (id)initWithCoder:(NSCoder *)decoder
{
if ( self = [super initWithCoder:decoder] ) {
[decoder
decodeValueOfObjCType:@encode(typeof(underlineWhenMouseIsOver))
at:&underlineWhenMouseIsOver];
}
return self;
}
-------------------------
which are very basic! I can't really see where the problem is.
anyone had the same issue? any advice?
Thank you for your help!
Giovanni Donelli
_______________________________________________
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.