【问题标题】:Can't restore archived data无法恢复存档数据
【发布时间】:2012-09-20 18:45:21
【问题描述】:

好的,上周我已经经历过一百万次了,但我就是不明白。 (是的,我已经阅读了 Apple 的文档。)

我正在归档我的对象,它似乎正在正确归档(我可以看到写入文件系统的文件,如果我检查它,我可以看到其中的数据)。但是,当我重新启动我的应用程序时,我的数据没有被恢复。我读到的每个例子都告诉我这是多么容易,但我就是不明白。一个独特的地方是我的对象是一个单例,它用于在视图控制器之间传递数据。

我非常感谢一些明智的建议。提前致谢。

这是我的标题:

#import <Foundation/Foundation.h>

@interface SharedAppDataObject : NSObject <NSCoding>
{
    NSMutableDictionary *apiKeyDictionary;
    NSString *skuFieldText;
    NSIndexPath *checkmarkIndex;
}

+ (SharedAppDataObject *)sharedStore;

@property (nonatomic, copy) NSString *skuFieldText;
@property (nonatomic, copy) NSIndexPath *checkmarkIndex;
@property (nonatomic, copy) NSMutableDictionary *apiKeyDictionary;

-(void)setValue:(NSString *)apiKey forKey:(NSString *)name;

-(void)setSkuField:(NSString *)s;
-(void)setCheckmarkIndex:(NSIndexPath *)p;

-(NSMutableDictionary *)apiKeyDictionary;
-(BOOL)saveChanges;

@end

这是我的实现:

#import "SharedAppDataObject.h"

@implementation SharedAppDataObject

@synthesize skuFieldText;
@synthesize checkmarkIndex;
@synthesize apiKeyDictionary;


    //create our shared singleton store
+(SharedAppDataObject *)sharedStore {

    static SharedAppDataObject *sharedStore = nil;

    if (!sharedStore) {
        sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];

        if(!sharedStore) 
            sharedStore = [[super allocWithZone:NULL] init];
    }
    return sharedStore;
}

-(id) init {
    self = [super init];
    if (self) {
    } 
    return self;
}

-(void)setValue:(id)apiKey forKey:(NSString *)name {
        [apiKeyDictionary setObject:apiKey forKey:name];
}

-(void)setSkuField:(NSString *)s {
    skuFieldText = s;
}

-(NSMutableDictionary *)apiKeyDictionary {  
    return apiKeyDictionary;
}

-(void)setCheckmarkIndex:(NSIndexPath *)p {
    checkmarkIndex = p;   
}

-(void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:skuFieldText forKey:@"skuFieldText"];
    [aCoder encodeObject:checkmarkIndex forKey:@"checkmarkIndex"];
    [aCoder encodeObject:apiKeyDictionary forKey:@"apiKeyDictionary"];
}

-(id)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    if (self) {
        [self setSkuFieldText:[aDecoder decodeObjectForKey:@"skuFieldText"]];
        [self setCheckmarkIndex:[aDecoder decodeObjectForKey:@"checkmarkIndex"]];
        [self setApiKeyDictionary:[aDecoder decodeObjectForKey:@"apiKeyDictionary"]];
    }
    return self;
}

+(NSString *)archivePath {
    NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDirectory = [documentDirectories objectAtIndex:0];
    return [documentDirectory stringByAppendingPathComponent:@"bbyo.archive"];
}

-(BOOL)saveChanges {      
    return [NSKeyedArchiver archiveRootObject:self toFile:[SharedAppDataObject archivePath]];  
}

@end

来自 App Delegate 的保存方法:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    BOOL success = [[SharedAppDataObject sharedStore] saveChanges];

    if (success) {
        NSLog(@"Saved all the data");
    } else {
        NSLog(@"Didn't save any of the data");
    }
}

【问题讨论】:

    标签: ios nskeyedarchiver nscoding


    【解决方案1】:

    application:didFinishLaunchingWithOptions: 中初始化sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];。该方法用于初始化数据结构和恢复之前的应用状态。

    另外,从sharedStore 中取出static SharedAppDataObject *sharedStore = nil;。如果保存文件存在,[ShareAppDataObject sharedStore] 将始终取消归档不必要的文件。它可以在初始化期间取消归档一次。

    这里有一个帖子可以解答你的问题:http://bit.ly/PJO8fM

    【讨论】:

    • 您链接到的示例非常完美。谢谢!
    【解决方案2】:

    我不能给你答案,但有一些想法可以解决这个问题。走这条线:

    sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];
    

    因此,如果 sharedStore 为 nil,则说明有问题 - 请对其进行测试。如果没有,则记录路径,并使用 NSFileManager 方法查看文件是否存在,它的大小等。如果你发现文件在那里并且有大小,但你不能取消归档它,这当然是一个问题。在这种情况下,请在创建文件后添加特殊的调试代码:

    -(BOOL)saveChanges {      
        BOO ret =  [NSKeyedArchiver archiveRootObject:self toFile:[SharedAppDataObject archivePath]];
        id foo = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];
        // check if foo is not nil, if its the proper class, etc.
    }
    

    如果您在保存文件时可以很好地取消存档,但在重新启动应用程序时无法解压,则说明文件有问题。所有这些信息都应该指向解决方案。

    另一个想法 - 当你对数据进行编码时,记录它,以确保它不是 nil - 但即使是这样,取消归档也应该工作。

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      • 2019-05-20
      • 1970-01-01
      相关资源
      最近更新 更多