我有一个小问题与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方法返回的类显示了正确的值,只有在退出该方法之后,预期的布尔值似乎才会作为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];** settings类的animateMenus成员现在将抛出以下内容:
-NSCFString animateMenus:无法识别的选择器发送到实例0xc712570 2010-10-15 11:12:51.828 App900:207 *由于未捕获的异常'NSInvalidArgumentException',正在终止应用程序,原因:'-NSCFString animateMenus:无法识别的选择器发送到实例0xc712570‘
然而,在应用程序启动时调用'settings = Settings LoadSettings;‘就可以解决这个问题(但总是使用应用程序的默认设置)?
Load和Save方法:
+ (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的所有其他成员都是instance。
发布于 2010-10-18 19:13:44
您需要做的是:
settings = [[Settings LoadSettings] retain];这是因为在您的LoadSettings中,NSKeyedUnarchiver的结果是一个自动释放的对象。它被释放了:-)在那个位置创建了一个新的对象,在本例中是一个NSString。
编辑:
嗯,我刚刚注意到了LoadSettings的一个主要问题,我一开始忽略了这个问题:你混合了内存释放策略:在一个代码路径中,你返回了不自动释放的[[Settings alloc] init]结果,而在另一个代码路径中,你保留了自动释放的NSKeyedArchiver结果。您需要确保只使用一个概念。
由于方法名LoadSettings在其名称中不包含alloc、copy或new,因此约定它应该返回一个自动释放的对象。因此,您应该这样做:
if (data == nil) {
s = [[Settings alloc] init];
[s Initialise];
[s SaveSettings];
[s autorelease];
}
else
...https://stackoverflow.com/questions/3958439
复制相似问题