2012-02-06 17 views
0

iOS 5アプリでアーカイブを動作させる方法を理解できません。初期化時に存在する場合、plistデータを取得するシングルトンセッションストアがあります。 SessionStoreはNSObjectから継承し、plistファイルからロードしたいNSMutableArray * allSessionsという1つのivarを持っています。ここにSessionStore.mがあります。問題が明らかか、もっと情報が必要なのかどうかわかりません...ありがとう! AppDelegate.mでネイサンシングルトンでinitWithCoderとNSUnarchiverを実装するのに手助けが必要

#import "SessionStore.h" 

static SessionStore *defaultStore = nil; 

@implementation SessionStore 

+(SessionStore *)defaultStore { 
    if (!defaultStore) { 
     // Load data.plist if it exists 
     NSString *pathInDocuments = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"data.plist"]; 
    NSFileManager *fileManager = [[NSFileManager alloc] init]; 
    if ([fileManager fileExistsAtPath:pathInDocuments]) 
     defaultStore = [NSKeyedUnarchiver unarchiveObjectWithFile:pathInDocuments]; 
    } else 
     defaultStore = [[super allocWithZone:NULL] init]; 

    return defaultStore; 
} 


+(id)allocWithZone:(NSZone *)zone { 
    return [self defaultStore]; 
} 

-(id)init { 
    if (defaultStore) 
     return defaultStore; 

    self = [super init]; 

    if (self) 
     allSessions = [[NSMutableArray alloc] init]; 

    return self; 
} 

-(NSMutableArray *)allSessions { 
    if (!allSessions) allSessions = [[NSMutableArray alloc] init]; 
    return allSessions; 
} 

-(void)setAllSessions:(NSMutableArray *)sessions { 
    allSessions = sessions; 
} 

-(void)encodeWithCoder:(NSCoder *)aCoder { 
    [aCoder encodeObject:allSessions forKey:@"All Sessions"]; 
} 

-(id)initWithCoder:(NSCoder *)aDecoder { 
    self = [SessionStore defaultStore]; 
    [self setAllSessions:[aDecoder decodeObjectForKey:@"All Sessions"]]; 
    return self; 
} 

それが終了時にplistファイル保存します。私は通常これを行う方法は、私は、私がする必要があるときに物事を保存し、データファイルを持つことです

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
    // Save data to plist file 
    NSString *pathInDocuments = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"data.plist"]; 

    [NSKeyedArchiver archiveRootObject:[SessionStore defaultStore] toFile:pathInDocuments]; 
} 
+0

どうしたのですか? –

+0

plistファイルを読み込もうとするとフリーズします。 "EXC_BAD_ACCESS"行:NSString * pathInDocuments = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory、NSUserDomainMask、YES)lastObject] stringByAppendingPathComponent:@ "data.plist"]; –

答えて

0

をオブジェクトが初期化されたときにそれらをバックアップしてください。したがって、このような何か:私はしたいとき

@interface SessionStore 
@property (nonatomic, copy) NSMutableArray *allSessions; 

- (void)loadData; 
- (void)saveData; 
@end 

static SessionStore *sharedInstance = nil; 

static NSString *const kDataFilename = @"data.plist"; 

@implementation SessionStore 

@synthesize allSessions = _allSessions; 

#pragma mark - 

+ (id)sharedInstance { 
    if (sharedInstance == nil) 
     sharedInstance = [[self alloc] init]; 
    return sharedInstance; 
} 


#pragma mark - 

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


#pragma mark - 

- (void)loadData { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:kDataFilename]; 

    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    if ([fileManager fileExistsAtPath:path]) { 
     NSMutableData *theData = [NSData dataWithContentsOfFile:path]; 
     NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingWithData:theData]; 
     self.allSessions = [[decoder decodeObjectForKey:@"allSessions"] mutableCopy]; 
     [decoder finishDecoding]; 
    } 

    if (!_allSessions) { 
     self.allSessions = [[NSMutableArray alloc] initWithCapacity:0]; 
    } 
} 

- (void)saveData { 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *path = [documentsDirectory stringByAppendingPathComponent:kDataFilename]; 

    NSMutableData *theData = [NSMutableData data]; 
    NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initForWritingWithMutableData:theData]; 

    [encoder encodeObject:_allSessions forKey:@"allSessions"]; 
    [encoder finishEncoding]; 

    [theData writeToFile:path atomically:YES]; 
} 

はその後、私は戻ってディスクにデータを保存するためにsaveDataを呼び出します。それは毎回allSessionsの変更、またはアプリが終了/バックグラウンドに入るたびに1回かもしれません。これは、どれくらいの頻度でallSessionsが変更され、データが確実に保存されるかが重要です。

シングルトンのコードは、sharedInstanceがraceyであることを心配している場合は、GCD dispatch_onceまたは類似のものを使用して、推論のためのStackOverflowをここで検索することは決して最善ではありません。

シングルトンオブジェクト全体をシリアライズしようとしているため、シングルトンオブジェクト全体をシリアライズしようとしているため、シンプトン自体の内容を理解するのが少し難しいと思っています。あなたのやり方のように、あなたのNSKeyedArchiverをアプリデリゲートに流出させるのではなく、

+0

うわー、ありがとう。シングルトンによって呼び出されるセーブとロードのメソッドで説明したように、あなたの方法ははるかにクリーンなようです。私は初心者なので、あなたが呼び出したメソッドのいくつかを調べなければなりません。私はそれらを認識しません。そして、それを動作させることができれば、アップデートを投稿します。ありがとう! –

+0

複数のバリエーションを試してもうまくいかなかった。私は本を​​打つつもりで、おそらくサンドボックスのアーカイブプロセスをテストして、問題を特定できるかどうかを調べるつもりです。あなたの助けをありがとう、しかし、私は努力を感謝します。 –

+0

@ NathanW何がうまくいかなかったのですか?私は使用するシングルトンでそのことを正確に行い、それは絶対にうまく動作します。何がおかしいの? – mattjgalloway

関連する問題