【发布时间】:2010-10-18 10:57:30
【问题描述】:
我在坚持我的 App Settings 类时遇到了 NSCoding 和 NSKeyedArchiver 的一个小问题,我希望有人能发现问题,如果这是我的代码,我对 Obj-C 相对较新,但在多种语言方面拥有丰富的编码经验,所以代码对我来说似乎还可以,但是...
我有一个实例类来保存我的应用程序设置,该类本身是主应用程序委托的保留属性,这是通过一个
@interface AppDelegate : NSObject <UIApplicationDelegate> {
Settings *settings;
[...]
}
@property (nonatomic, retain) Settings *settings;
[...]
这是在 applicationDidFinishLaunching 事件中创建的:
settings = [Settings LoadSettings];
如果我注释掉上面的行,那么应用程序每次都可以正常工作,但是如果我使用 NSCoder 和 NSKeyedUnarchiver 从持久设置中拉回对象,则会抛出 SIGARBT 错误,因为正在发送 NSCFString 选择器以获取编码为布尔属性?设置类被定义为实现协议的 NSObject。
@interface Settings : NSObject <NSCoding>
正如我所说,创建设置类的实例很好,没有问题,保存它似乎还可以,并且从 LoadSettings 方法检查返回的类显示正确的值,只有在退出该方法后才会达到预期的效果bool 值似乎作为 NSCFString 被发送到 load 方法
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
[...]
self.animateMenus = [decoder decodeBoolForKey:@"animateMenus"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[...]
[encoder encodeBool:animateMenus forKey:@"animateMenus"];
}
加载设置后,相关属性的使用方式如下:
SettingsViewController *settingsView = [[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:nil];
[self presentModalViewController:settingsView animated:[AppDelegate instance].settings.animateMenus];
[settingsView release];
**设置类的 animateMenus 成员现在将抛出以下内容:
-[NSCFString animateMenus]:无法识别的选择器发送到实例 0xc712570 2010-10-15 11:12:51.828 App[900:207] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[NSCFString animateMenus] : 无法识别的选择器发送到实例 0xc712570'
而,采用 'settings = [Settings LoadSettings];'调用应用程序启动可以解决问题(但始终使用应用程序默认值)?
加载和保存方法:
+ (Settings*) LoadSettings {
Settings *s = nil;
@try {
NSData *data = [[NSUserDefaults standardUserDefaults] objectForKey:@"settings"];
if (data == nil) {
s = [[Settings alloc] init];
[s Initialise];
[s SaveSettings];
}
else
s = (Settings*)[NSKeyedUnarchiver unarchiveObjectWithData:data];
}
@catch (NSException * e) {
NSLog(@"Error Loading Settings\n%@", [e reason]);
}
@finally {
return s;
}
}
// Saves the settings dictionary to the user's device documents folder..
- (void) SaveSettings {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"settings"];
}
Load 是一个静态方法,Settings 的所有其他成员都是实例。
【问题讨论】:
标签: iphone