I'm trying to store some custom class/data to a file in my iPhone/iPad app.
I have a Class RSHighscoreList
@interface RSHighscoreList : NSObject {
NSMutableArray *list;
}
which contains objects of RSHighscore in the list
@interface RSHighscore : NSObject {
NSString *playerName;
NSInteger points;
}
When I try to store all to file
- (void)writeDataStore {
RSDataStore *tmpStore = [[RSDataStore alloc] init];
_tmpStore.highscorelist = self.highscorelist.list;
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:tmpStore forKey:kDataKey];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
[archiver release];
[data release];
}
@interface RSDataStore : NSObject <NSCoding, NSCopying> {
NSMutableArray *highscorelist;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:highscorelist forKey:@"Highscorelist"];
}
The app will crash with an error message
-[RSHighscore encodeWithCoder:]: unrecognized selector sent to instance 0x573cc20 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RSHighscore encodeWithCoder:]: unrecognized selector sent to instance 0x573cc20'
I wonder why the error tells about RSHighscore, even if that is 'wrapped'. Does anyone have a good idea?
The class you're going to encode or initWithCoder should conform to
<NSCoding>
protocol So you just should add this in your interface, otherwise indeed the runtime will not recognize the selector as it's the part of<NSCoding>
protocolRSDataStore
has an-encodeWithCoder:
method, but (according to the error message)RSHighscore
doesn't. You need to implement the NSCoding protocol for every class you're serializing.If the base class of
RSHighscore
is ever changed to something other thanNSObject
, the-initWithCoder:
method might need to be changed to call[super initWithCoder:decoder]
rather than[super init]
. Alternatively, add<NSCoding>
to NSObject and changeRSHighscore
's-initWithCoder:
now.