2016-02-03 156 views
1

我有一個ObjC iOS應用程序,用於存檔/取消存檔數據。有問題的數據來自同伴服務器。每個用戶都獲得一組不同的數據。如何使用[NSKeyedUnarchiver unarchiveObjectWithFile]防止損壞的文件崩潰?

雖然我從來沒有遇到過用戶投訴,我看到通過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之內),並且如果讀取失敗,則會執行某些操作以將狀態詳細信息報告給我。我還需要找到另一種緩存這些用戶數據的方式,但這很容易。

回答

0

雖然try/catch的使用應該有點罕見,但對於它的使用來說,這是一個非常有效的用例。由於意外文件導致應用程序崩潰。這是你的應用程序應該處理的事情,並且可以很容易從中恢復捕捉例外情況,試圖解壓縮一個不良文件,並向用戶報告適當的錯誤或以其他適當的方式處理它。

我在代碼中的一個應用程序中執行相同的操作,在該代碼中,我解壓縮用戶可導入應用程序的zip文件。用戶可能已經導入了除zip文件以外的內容。所以我用try/catch包裝瞭解壓縮代碼。 catch基本上顯示錯誤,讓用戶知道該zip文件無效。