Re: Odd problem using NSCoding
Re: Odd problem using NSCoding
- Subject: Re: Odd problem using NSCoding
- From: Ricky Sharp <email@hidden>
- Date: Wed, 06 Apr 2005 06:13:34 -0500
On Wednesday, April 06, 2005, at 02:37AM, <email@hidden> wrote:
>Hey there. I have a simple doc-based app that manages a single model object. The model object implements NSCoding and also overrides initWithCoder and encodeWithCoder. I then use an NSKeyedArchiver in MyDocument to archive the object to disk (archiveDataWithRootObject) in dataRepresentationOfType. Also use an NSKeyedUnarchiver to unarchive the model object back (unarchiveObjectWithData) in loadDataRepresentation:ofType:.
>
>My interface elements are properly bound to my model object instance variables. But when I try to "open" a file that I previously saved, I get the following from the Log window twice:
>
>[TradeModel copyWithZone:]: selector not recognized [self = 0x3ee2e0]
copyWithZone: belongs to the NSCopying protocol and not NSCoding. Sometimes you have to provide copyWithZone.
>Now, two of my model instances are int primitives, and I was encoding and decoding using NSNumber class methods, like so:
>
>- (void)encodeWithCoder:(NSCoder*)coder
>{
> [coder encodeObject:[NSNumber numberWithInt:[self tradeTypeValue]]];
> [coder encodeObject:[NSNumber numberWithInt:[self tradeStatusValue]]];
> [coder encodeObject:[self traderName]]; // NSString var
> [coder encodeObject:[self traderAddress]]; // NSString var
>}
If TradeModel's superclass conforms to NSCoding, you'll need to call super's encodeWithCoder before you encode your ivars.
Also, there's no need to wrap non-object ivars (e.g. int with NSNumber). Look at using encodeValueOfObjCType instead. Or, if you're able to use NSKeyedArchiver, look into using encodeObject:forKey:, encodeInt:forKey:, etc. This will shield you from having to encode/decode in a particular order.
>
>(id)initWithCoder:(NSCoder*)coder
>{
> [super init];
> [self setTradeTypeValue:[[coder decodeObject] intValue]];
> [self setTradeStatusValue:[[coder decodeObject] intValue]];
> [self setTraderName:[coder decodeObject]];
> [self setTraderAddress:[coder decodeObject]];
> return self;
>}
Again, if the superclass conforms to NSCoding, you'll need to call super's initWithCoder.
Also, this method should really be implemented something like this:
if ((self = [super init]) != nil) // or initWithCoder:
{
// set ivars
}
return self;
And, if you can use NSKeyedUnarchiver, look at using decodeObjectForKey:, decodeIntForKey:, etc.
--
Rick Sharp
Instant Interactive(tm)
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden