So I have a project that uses the old-style encodeObject:/decodeObject NSCoder serialization. I need to add a new object to the serialization process but previously saved documents will crash as decodeObject tries to decode something that's not there (yet).
-(void) encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
[aCoder encodeObject:existingArray];
[aCoder encodeObject:anotherExistingArray];
[aCoder encodeObject:myNewArray];
}
-(id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if( self != nil ) {
NSArray *_existingArray = [aDecoder decodeObject];
NSArray *_anotherExistingArray = [aDecoder decodeObject];
// We crash here, this object doesn't exist in documents saved with only the first two arrays
NSArray *_myNewArray = [aDecoder decodeObject];
}
return( self );
}
I don't think I can convert this to a keyed archive and maintain compatibility with previously saved archives (which is a requirement). Trying to catch the exception that's thrown doesn't seem to help either.
Any ideas?
UPDATE: Bah, why is it when you ask a question you almost immediately find the answer yourself?
This class was versioned correctly. Previous author had a bug in the version check. So for completeness:
+ (void) initialize {
if( self == [MyClass class] ) {
[self setVersio开发者_运维技巧n:2]; // was 1
}
}
-(void) encodeWithCoder:(NSCoder *)aCoder {
[super encodeWithCoder:aCoder];
[aCoder encodeObject:existingArray];
[aCoder encodeObject:anotherExistingArray];
[aCoder encodeObject:myNewArray];
}
-(id) initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
int version = [aDecoder versionForClassName:@"MyClass"];
if( self != nil ) {
NSArray *_existingArray = [aDecoder decodeObject];
NSArray *_anotherExistingArray = [aDecoder decodeObject];
if( version > 1 ) {
NSArray *_myNewArray = [aDecoder decodeObject];
}
}
return( self );
}
Continue to read old files (read-only) with serial archiver.
Load and save new files with keyed archiver, detect by:
[NSCoder allowsKeyedCoding]
精彩评论