0

私はiPhoneアプリを書いています–いくつかのソーシャルネットワークのクライアントです。アプリは複数のアカウントをサポートしています。アカウントに関する情報は、キー付きアーカイブに保存されます。

保存に使用される方法:

- (void) saveAccounts {
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *path = [paths objectAtIndex:0];
 path = [path stringByAppendingPathComponent:@"accounts.bin"];
 // NSMutableArray *accounts = ...;
 [NSKeyedArchiver archiveRootObject:accounts toFile:path];
}

読み取りに使用するメソッド:

- (NSMutableArray *) loadAccounts {
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *path = [paths objectAtIndex:0];
 path = [path stringByAppendingPathComponent:@"accounts.bin"];
 NSMutableArray *restoredAccounts = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
 return [restoredAccounts retain];
}

このメソッドsaveAccountsは、一部のアカウントが追加/変更/削除された場合にのみ使用されます。このメソッドloadAccountsは、アプリが起動するたびに使用されます。このファイルにアクセスする他のコードはありません。

私と私のテスターの1人が問題を抱えています。ある瞬間、のように振る舞い始めるのaccounts.binが欠けています。loadAccountsが返された場合nil、アプリはアカウントの追加を提案します。アカウントを入力した後(アプリは呼び出す必要がありますsaveAccounts)、アプリは正常に動作しますが、再度起動すると、アカウントを再度追加するように求められます。唯一の解決策は、アプリをiPhoneに再インストールすることです。再インストールした後は、問題が発生してもしばらくは機能します。

私たち(問題が発生した私と私のテスター)は、3.1.2でiPhone3Gを使用しています。3.1.2を搭載したiPhone3GSでこの問題が発生しなかった別のテスター。

このファイルが消える理由はありますか?

アップデート

コードにバグが見つかりました。ドキュメントディレクトリ全体を削除するコードがありました。コードのこの部分はリモートサーバーに関連しているため、このコードを追跡することは困難でした。バグは非常にまれな条件下でのみ発生しました。

これでバグが見つかり、コードが修正されました。wkwの答えは私の問題を解決しませんでしたが、それは私にもっと深く掘り下げることを余儀なくさせました。ありがとうございました!

4

1 に答える 1

0

-- デバッグ デバイスとして -- loadAccounts で、または少なくとも unarchiver が nil を返すたびに、Documents ディレクトリの内容を確認します。ディレクトリ内のファイルの名前を取得するためのコードを以下に示します。ブレークポイントを設定し、NSArray をダンプして項目を表示します。
ファイルが Docs ディレクトリに存在することがわかる場合、問題は別の場所にあります。アーカイブに失敗した可能性があります。データをアーカイブする呼び出しの戻り値を確認します。

if( ! [NSKeyedArchiver archiveRootObject:accounts toFile:path] ){
    NSLog(@"Oooops! account data failed to write to disk");
}

ディレクトリ内のファイルの名前を取得:

- (NSArray*) directoryContentsNames:(NSString*) directoryPath {
    NSArray* result;
    {
        result = [[NSFileManager defaultManager]
            directoryContentsAtPath: directoryPath];
    }
    if( result && [result count] > 0 ){
        NSMutableArray *items = [[[NSMutableArray alloc] init] autorelease];
        for( NSString *name in result ){
            if( ! [name isEqualToString:@".DS_Store"] )
                [items addObject: name];
        }
        result = items;

    }
    return result;
}

おそらく NSUserDefaults の方が使いやすいでしょうか?

また、NSArray の writeToFile の代わりに Keyed(Un)Archiver を使用する理由はありますか?

if( ! [accounts writeToFile:path atomically:YES] )
    ; // do something since write failed

ファイルを読み取るには:

NSMutableArray *accounts = [[NSArray arrayWithContentsOfFile:path] mutableCopy];
于 2009-11-08T19:18:52.363 に答える