我正在寫一個iPhone應用程序,並嘗試存檔設置時出現問題。我正在使用一個類(AppData)來保存設置(該示例目前只顯示一個),並在應用程序加載時使用App Delegate創建AppData實例,並在應用程序終止時將其存儲。我符合(我認爲)的NSCoding協議錯誤使用NSKeyedUnarchiver
該應用程序將文件存儲在文檔目錄中確定,並檢查文件結構似乎持有我期望的數據。然而,當該文件中的取檔加載返回錯誤
***
終止應用程序由於未捕獲的異常「NSInvalidUnarchiveOperationException」,原因:***
- [NSKeyedUnarchiver decodeObjectForKey:]:取檔已完成;無法解碼任何更多'
我一直在摔跤這一段時間,所以如果任何人都可以看到這個問題,我會非常感激。
代碼:
應用代表:
接口:
#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
最後constants.h
//此文件包含所有的應用程序常數
#define kSettingsFilename @"archive" //Filename where all application settings are stored
#define kSettingsKey @"settingsKey" //Key name
#define kDataKey @"data"
謝謝奧萊,不知道有多少次我讀過這段代碼,錯過了一些非常明顯的東西。 – 2010-06-27 20:19:02
我只是爲了簡化,謝謝你的提示。 – 2010-06-27 20:21:30