首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用NSKeyedUnarchiver出错

使用NSKeyedUnarchiver出错
EN

Stack Overflow用户
提问于 2010-06-27 09:56:08
回答 1查看 933关注 0票数 0

我正在编写一个iPhone应用程序,并且在试图归档设置时遇到了问题。我使用一个类( AppData )来保存设置(示例目前只显示一个),并在应用程序加载时使用AppData创建AppData实例,并在应用程序结束时存储它。我遵守(我认为) NSCoding协议。

应用程序将文件存储在Documents目录OK中,检查文件结构似乎保存了我期望的数据。但是,当文件加载到未存档程序中时,返回错误。

***终止应用程序,原因是“NSInvalidUnarchiveOperationException”异常,原因:*** -NSKeyedUnarchiver decodeObjectForKey::unarchiver已完成;无法再解码任何内容

我和这个问题斗争了一段时间了,所以如果有人能看到这个问题,我会非常感激的。

代码:

应用程序代表:

接口:

代码语言:javascript
复制
#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

执行情况:

代码语言:javascript
复制
#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

AppData类:

接口:

代码语言:javascript
复制
#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

执行情况:

代码语言:javascript
复制
#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

终于定式了。

//此文件包含所有应用程序常量

代码语言:javascript
复制
#define kSettingsFilename   @"archive"  //Filename where all application settings are stored

#define kSettingsKey        @"settingsKey"      //Key name
#define kDataKey            @"data"
EN

回答 1

Stack Overflow用户

发布于 2010-06-27 10:05:19

正如错误消息声明的那样,您正在完成解码之前调用finishDecoding。然后你又叫它:

代码语言:javascript
复制
[unarchiver finishDecoding];    
appData = [unarchiver decodeObjectForKey:kDataKey];
[unarchiver finishDecoding];

那是行不通的。

也就是说,您的代码比需要的要复杂得多。为什么不这样做:

代码语言:javascript
复制
// Encoding:
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:appData];

// Decoding:
appData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3127019

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档