我正在编写一个iPhone应用程序,并且在试图归档设置时遇到了问题。我使用一个类( AppData )来保存设置(示例目前只显示一个),并在应用程序加载时使用AppData创建AppData实例,并在应用程序结束时存储它。我遵守(我认为) NSCoding协议。
应用程序将文件存储在Documents目录OK中,检查文件结构似乎保存了我期望的数据。但是,当文件加载到未存档程序中时,返回错误。
***终止应用程序,原因是“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];
}
@endAppData类:
接口:
#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终于定式了。
//此文件包含所有应用程序常量
#define kSettingsFilename @"archive" //Filename where all application settings are stored
#define kSettingsKey @"settingsKey" //Key name
#define kDataKey @"data"发布于 2010-06-27 10:05:19
正如错误消息声明的那样,您正在完成解码之前调用finishDecoding。然后你又叫它:
[unarchiver finishDecoding];
appData = [unarchiver decodeObjectForKey:kDataKey];
[unarchiver finishDecoding];那是行不通的。
也就是说,您的代码比需要的要复杂得多。为什么不这样做:
// Encoding:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:appData];
// Decoding:
appData = [NSKeyedUnarchiver unarchiveObjectWithData:data];https://stackoverflow.com/questions/3127019
复制相似问题