iPhone应用程序丢失文件

时间:2009-11-08 19:05:40

标签: iphone nskeyedarchiver

我正在编写一个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上,重新安装后它可以解决任何问题。

我们(我和我的测试人员遇到问题)使用iPhone 3G和3.1.2。 另一位没有在他的iPhone 3GS 3.1.2上遇到过这个问题的测试人员。

为什么这个文件会消失的想法?

更新

我在代码中发现了错误。有一个代码删除整个Document目录。因为代码的这一部分是与远程服务器相关的,所以很难跟踪这段代码。 Bug只在非常罕见的条件下出现。

现在发现了错误,并且代码已得到纠正。 wkw的答案没有解决我的问题,但它迫使我深入挖掘。谢谢!

1 个答案:

答案 0 :(得分:0)

如何 - 作为调试设备 - 在loadAccounts中验证Documents目录的内容,或者至少在unarchiver返回nil时。下面有一些代码来获取目录中文件的名称。设置一个断点,然后转储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可能更容易使用?

另外,是否有理由使用Keyed(Un)Archiver而不是NSArray的writeToFile?

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

并阅读以下文件:

NSMutableArray *accounts = [[NSArray arrayWithContentsOfFile:path] mutableCopy];