题
我正在编写一个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
每次应用程序启动时都使用。没有其他代码访问此文件。
我和我的一位测试人员会遇到问题。在某个时刻的开始就像 accounts.bin
不见了。如果 loadAccounts
返回 nil
, ,该应用程序提供了添加帐户。输入帐户后(应用必须致电 saveAccounts
),该应用程序正常工作,但是当我再次启动它时,它要求我再次添加帐户。唯一的解决方案是将应用程序重新安装到iPhone之后,在重新安装后,它可以解决任何麻烦。
我们(我和我的测试人员都会出现问题)使用3.1.2的iPhone 3G。另一位测试师没有在3.1.2的iPhone 3GS上遇到此问题。
有什么想法为什么这个文件消失了?
更新
我在代码中找到了错误。有一个代码删除整个文档目录。由于代码的这一部分与远程服务器相关,因此很难跟踪此代码。虫子仅在非常罕见的条件下出现。
现在找到了错误,并纠正了代码。 WKW的答案并没有解决我的问题,但这迫使我更深入地挖掘了我的问题。谢谢!
解决方案
怎么样 - 作为调试设备,在LoadAccounts中或至少每当Unarchiver返回零时,验证文档目录的内容。下面有一些代码可以在目录中获取文件名。设置一个断点,然后倾倒NSArray即可查看项目。
如果您可以看到该文件存在于Docs DIR中,那么您的问题就在其他地方。也许它没有成功存档。检查呼叫归档数据的返回值:
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可能更容易使用?
另外,是否有理由使用键盘(UN)档案仪而不是NSArray的Writetofile?
if( ! [accounts writeToFile:path atomically:YES] )
; // do something since write failed
并读取文件:
NSMutableArray *accounts = [[NSArray arrayWithContentsOfFile:path] mutableCopy];