iphone - 使用 NSCoder 保存自己的类

标签 iphone objective-c save nscoder

我正在尝试将一些自定义类/数据存储到我的 iPhone/iPad 应用程序中的文件中。

我有一个类 RSHighscoreList

@interface RSHighscoreList : NSObject {
    NSMutableArray *list;
}

列表中包含RSHighscore的对象

@interface RSHighscore : NSObject {
    NSString *playerName;
    NSInteger points;
}

当我尝试将所有内容存储到文件中时

- (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"];
}

应用程序将崩溃并显示错误消息

-[RSHighscore encodeWithCoder:]: unrecognized selector sent to instance 0x573cc20
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RSHighscore encodeWithCoder:]: unrecognized selector sent to instance 0x573cc20'

我想知道为什么错误会提示 RSHighscore,即使它是“包装”的。有人有好主意吗?

最佳答案

RSDataStore有一个 -encodeWithCoder:方法,但是(根据错误消息)RSHighscore没有。您需要实现 NSCoding您正在序列化的每个类的协议(protocol)。

@implementation RSHighscore
static NSString *const kPlayerName = @"PlayerName";
static NSString *const kPoints = @"Points";

-(id)initWithCoder:(NSCoder *)decoder {
    if ((self=[super init])) {
        playerName = [[decoder decodeObjectForKey:kPlayerName] retain];
        points = [decoder decodeIntegerForKey:kPoints];
    }
    return self;
}
-(void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:playerName forKey:kPlayerName];
    [encoder encodeInt:points forKey:kPoints];
}
...

如果RSHighscore的基类曾经更改为 NSObject 以外的内容, -initWithCoder:可能需要更改方法以调用 [super initWithCoder:decoder]而不是 [super init] .或者,添加 <NSCoding>到 NSObject 并更改 RSHighscore-initWithCoder:现在。

@interface NSObject (NSCoding)
-(id)initWithCoder:(NSCoder*)decoder;
-(void)encodeWithCoder:(NSCoder*)encoder;
@end

@implementation NSObject (NSCoding)
-(id)initWithCoder:(NSCoder*)decoder {
    return [self init];
}
-(void)encodeWithCoder:(NSCoder*)encoder {}
@end

@implementation RSHighscore
-(id)initWithCoder:(NSCoder *)decoder {
    if ((self=[super initWithCoder:decoder])) {
        playerName = [[decoder decodeObjectForKey:kPlayerName] retain];
        points = [decoder decodeIntegerForKey:kPoints];
    }
    return self;
}
...

关于iphone - 使用 NSCoder 保存自己的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317164/

相关文章:

iphone - 有没有其他方法可以使用动画 block 来执行此动画?

objective-c - 保留属性指向错误的地址

ios - AFXMLRequestOperation 与 Google 文档

iOS Objective c - 在用户登录后将 uiviewcontroller 设置为 feed 屏幕,然后重新启动应用程序

java - 我怎样才能得到过滤后的模型?

mysql - 简单的 Flex Paint 应用程序,如何以非图像形式保存在数据库中

ios - 在功能选项卡上添加背景模式

iphone - iphone 应用程序的 SSL Wrapper

android - 如何自动保存和加载用户输入的kivy

ios - iOS 中的 Coreplot 构建失败问题