Save own Class with NSCoder(使用 NSCoder 保存自己的类)
问题描述
我正在尝试将一些自定义类/数据存储到我的 iPhone/iPad 应用程序中的文件中.
I'm trying to store some custom class/data to a file in my iPhone/iPad app.
我有一个类 RSHighscoreList
I have a Class RSHighscoreList
@interface RSHighscoreList : NSObject {
NSMutableArray *list;
}
列表中包含 RSHighscore 的对象
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'
我想知道为什么错误会告诉 RSHighscore,即使它是包装的".有人有好主意吗?
I wonder why the error tells about RSHighscore, even if that is 'wrapped'. Does anyone have a good idea?
推荐答案
RSDataStore
有一个-encodeWithCoder:
方法,但是(根据报错信息)RSHighscore
没有.您需要实现 NSCoding 您正在序列化的每个类的协议.
RSDataStore
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.
@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:
.
If the base class of RSHighscore
is ever changed to something other than NSObject
, the -initWithCoder:
method might need to be changed to call [super initWithCoder:decoder]
rather than [super init]
. Alternatively, add <NSCoding>
to NSObject and change RSHighscore
's -initWithCoder:
now.
@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;
}
...
这篇关于使用 NSCoder 保存自己的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 NSCoder 保存自己的类
基础教程推荐
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01