我正在编写一个 iPhone 应用程序,但在尝试存档设置时遇到了问题。我正在使用一个类 (AppData) 来保存设置(该示例目前仅显示一个),并使用 App Delegate 在应用加载时创建 AppData 的实例,并在应用终止时存储它。我符合(我认为)NSCoding 协议
该应用程序将文件存储在 Documents 目录中,并且检查文件结构似乎包含我期望的数据。但是,当文件在 unarchiver 中加载时返回错误
***
由于未捕获的异常“NSInvalidUnarchiveOperationException”而终止应用程序,原因:***
-[NSKeyedUnarchiver decodeObjectForKey:]:unarchiver 已完成;无法再解码任何东西'
我一直在努力解决这个问题,所以如果有人能看到这个问题,我将非常感激。
代码:
应用代表:
界面:
#import <UIKit/UIKit.h>
#import "AppData.h"
#import "Constants.h"
@interface iLeanAppDelegate : NSObject <UIApplicationDelegate> {
AppData *appData;
UIWindow *window;
UITabBarController *tabBarController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
@property (nonatomic, retain) AppData *appData;
@end
执行:
#import "iLeanAppDelegate.h"
@implementation iLeanAppDelegate
@synthesize window;
@synthesize tabBarController;
@synthesize appData;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
appData = [[AppData alloc] init];
if ([[NSFileManager defaultManager] fileExistsAtPath:[AppData dataFilePath]]) { //If previous settings have been found retrieve and initialise
NSData *data = [[NSMutableData alloc] initWithContentsOfFile:[AppData dataFilePath]];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
[unarchiver finishDecoding];
appData = [unarchiver decodeObjectForKey:kDataKey];
[unarchiver finishDecoding];
[unarchiver release];
[data release];
}
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
}
-(void)applicationWillTerminate:(NSNotification *)notification {
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:appData forKey:kDataKey];
[archiver finishEncoding];
BOOL success = [data writeToFile:[AppData dataFilePath] atomically:YES];
if (success)
NSLog(@"OK");
else
NSLog(@"Problem here");
[archiver release];
[data release];
}
- (void)dealloc {
[tabBarController release];
[window release];
[appData release];
[super dealloc];
}
@end
应用数据类:
界面:
#import <Foundation/Foundation.h>
#import "Constants.h"
@interface AppData : NSObject <NSCoding, NSCopying> {
BOOL audioAlert; //YES = audio alerts are on, NO = audio alerts are off
}
+(NSString *)dataFilePath;
@property(nonatomic, assign) BOOL audioAlert;
@end
执行:
#import "AppData.h"
@implementation AppData
@synthesize audioAlert;
+(NSString *)dataFilePath {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:kSettingsFilename];
}
#pragma mark NSCoding
-(void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeBool:audioAlert forKey:kSettingsKey];
}
-(id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.audioAlert = [decoder decodeObjectForKey:kSettingsKey];
}
return self;
}
#pragma mark -
#pragma mark NSCopying
-(id)copyWithZone:(NSZone *)zone {
AppData *copy = [[[self class] allocWithZone: zone] init];
//Will do this once coding works
return copy;
}
@end
最后是常量.h
//此文件包含所有应用程序常量
#define kSettingsFilename @"archive" //Filename where all application settings are stored
#define kSettingsKey @"settingsKey" //Key name
#define kDataKey @"data"