如何使用[NSKeyedUnarchiver unarchiveObjectWithFile]防止损坏文件崩溃?

时间:2016-02-03 21:52:34

标签: ios objective-c nskeyedunarchiver

我有一个ObjC iOS应用程序,我在其中存档/取消归档数据。有问题的数据来自配套服务器。每个用户都会获得一组不同的数据。

虽然我从未收到过用户投诉,但我发现Crashlytics在这一行上报告的崩溃数量非常少:

NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithFile:path];

崩溃细节:

Fatal Exception: NSInvalidArgumentException
*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive (0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30)

崩溃发生在大约0.002%的会话中,但在少数未知用户中最常见。

我发现了这个相关的问题:Archiving / Unarchiving results in initForReadingWithData incomprehensible archive。讨论为原因提供了两种合理的理论;一个存档包含字符" bplist" (听起来很合理),另一个涉及存档的大小(不太可能给出典型的数据集大小)。

我正在寻找有关如何检测这种情况并以某种方式行动以避免崩溃的建议。 NSKeyedArchiver似乎没有返回错误的方法 - 失败的存档是崩溃。

理想情况下,我更喜欢某种机制来在问题发生之前检测问题的根本原因。这个问题的频率并不能证明我编写自己的归档解析器是正确的,也不能证明添加所有用户都会执行的任何疯狂的风险。

我避免@try阻止了练习。显然这是一种可能性。应用程序读取此存档的频率远远超过写入,因此我的想法是在写入之后尝试读取(在@try内部),如果读取失败,则会向我报告状态详细信息。我还需要找到另一种方法来缓存这些用户的数据,但这很容易。

1 个答案:

答案 0 :(得分:0)

虽然使用try/catch应该有点罕见,但这是一个非常有效的用例。由于意外文件导致您的应用崩溃是不利的。这是您的应用应该处理的内容,并且可以轻松恢复。通过尝试取消归档坏文件并向用户报告适当的错误或以其他适当的方式处理它来捕获异常。

我在代码中的一个应用程序中也这样做,我解压缩用户可以导入应用程序的zip文件。用户可能导入了zip文件以外的内容。所以我用try/catch包装解压缩代码。 catch基本上会向用户显示错误,让他们知道zip文件无效。