質問
私は、ソーシャルネットワークのクライアントである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に再インストールすることです。再インストール後、問題が発生するとしばらく動作します。
私たち(私と問題が発生した私のテスター)は、iPhone 3Gを3.1.2で使用します。 3.1.2でiPhone 3GSでこの問題を経験しなかった別のテスター。
このファイルが消える理由はありますか?
アップデート
コードにバグが見つかりました。ドキュメントディレクトリ全体を削除するコードがありました。コードのこの部分はリモートサーバーに関連するため、このコードをトレースすることは困難でした。バグは非常にまれな条件でのみ現れました。
これでバグが見つかり、コードが修正されました。 WKWの答えは私の問題を解決しませんでしたが、それは私に深く掘り下げることを余儀なくされました。ありがとうございました!
解決
デバッグデバイスとして、LoadAccountsのドキュメントディレクトリのコンテンツを確認するか、少なくともUnarchiverがnilを返すたびに、どのようにしてください。ディレクトリ内のファイルの名前を取得するためのコードが以下にあります。ブレークポイントを設定し、nsarrayをダンプしてアイテムを表示します。
ドキュメント監督にファイルが存在することがわかる場合、問題は他の場所にあります。おそらくそれは正常にアーカイブしなかったでしょう。データをアーカイブするための呼び出しの返品値を確認してください。
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];