1

わかりました、私は先週これを100万回超えましたが、私はそれを得ていません. (そして、はい、私は Apple のドキュメントを読みました。)

オブジェクトをアーカイブしていますが、正しくアーカイブされているように見えます (ファイル システムに書き込まれたファイルを確認でき、それを調べると、その中のデータを確認できます)。ただし、アプリを再起動すると、データが復元されません。私が読んだすべての例は、これがいかに簡単かを教えてくれますが、私はそれを理解していません. ユニークな点の 1 つは、私のオブジェクトがシングルトンであり、View Controller 間でデータを渡すために使用されることです。

賢明なアドバイスをいただければ幸いです。前もって感謝します。

これが私のヘッダーです:

#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");
    }
}
4

2 に答える 2

0

で初期化sharedStore = [NSKeyedUnarchiver unarchiveObjectWithFile:[SharedAppDataObject archivePath]];application:didFinishLaunchingWithOptions:ます。このメソッドは、データ構造を初期化し、以前のアプリの状態を復元するために使用されます。

static SharedAppDataObject *sharedStore = nil;また、から取り出しsharedStoreます。保存ファイルが存在する場合は、[ShareAppDataObject sharedStore]必要のないファイルを常に解凍します。初期化中に一度アーカイブを解除できます。

あなたの問題に答えることができる投稿は次のとおりです: http://bit.ly/PJO8fM

于 2012-09-21T01:49:41.060 に答える
0

私はあなたに答えを与えることはできませんが、これを理解するためのいくつかのアイデア。この行を取る:

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ではないことを確認してください-しかし、そうであっても、アーカイブ解除は機能するはずです。

于 2012-09-20T19:27:56.830 に答える