Skip navigation.
 
mlRe: Odd problem using NSCoding
FROM : Ricky Sharp
DATE : Wed Apr 06 13:13:34 2005

On Wednesday, April 06, 2005, at 02:37AM, <<email_removed>> 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)

Related mailsAuthorDate
mlOdd problem using NSCoding <java_nutt Apr 6, 09:37
mlRe: Odd problem using NSCoding Ricky Sharp Apr 6, 13:13
mlRe: Re: Odd problem using NSCoding <java_nutt Apr 6, 13:48
mlRe: Re: Odd problem using NSCoding Ricky Sharp Apr 6, 15:00
mlRe: Odd problem using NSCoding Kevin Callahan Apr 9, 06:42