2015-03-19 179 views
0

我的一個項目中有用戶要求在本地保存數據以防突然出現應用程序崩潰的需求。其基於表單的應用程序使用戶填寫表單中的大量數據,如果應用程序突然崩潰,則用戶丟失了輸入的所有數據。iOS在應用程序崩潰時保存數據

應用程序正在使用核心數據在本地保存數據。

有一點我們將輸入的數據保存在覈心數據中,而不是每隔一秒用戶填充數據。

此外,如果應用程序崩潰的核心數據也消失。

+0

這是一個不好的要求。正確的要求是:修復錯誤,以免應用程序崩潰。使用單元測試以及使用工具進行自動應用程序測試,以確保您沒有崩潰的錯誤。 – Kerni 2015-03-19 12:09:07

回答

2

事實上,如果你的應用程序崩潰,則回調:

- (void)applicationWillTerminate:(UIApplication *)application 

不會被調用。如果由於某些原因系統需要關閉您的應用(通常是因爲資源很少或者因爲您的後臺作業在最長時間允許後仍然在工作),或者您處於iO4狀態,您只能調用此選項。您不需要有什麼方法可以知道你的應用何時崩潰(但是當你重啓應用時,你可以知道它是否崩潰)。

因此,對於您的特定情況下,有兩種解決方法:

  • 既可以使用的NSTimer一個快速射速,或致電fonction每次編輯的字段和更新核心數據上下文,然後保存它在磁盤上。

    NSError *error = nil; 
    [managedObjectContext save:&error] 
    

    您是否在上下文中設置了persistentStoreCoordinator?如果否,核心數據永遠不會將數據保存在磁盤上。

  • 崩潰不會出現任何地方,找到崩潰可能發生的地方並修復它,或者如果你不能,使用try-catch保持你的應用程序運行。

希望這有助於

+2

除了'try-catch'部分外,這大部分都是正確的。這不是對iOS問題的適當處理,因爲例外總是致命的,而且您有造成更多損害的風險,而不是更好!請參閱http://stackoverflow.com/questions/3378696/iphone-try-end-try/3379240#3379240 – Kerni 2015-03-19 12:12:31

1

特別情況下你可以 應該 使用,try catch塊,(但不是) 到處

try { 
    //write your code 
}catch(NSException *e){ 
    //See what's the error 
}finally{ 
    //Save your context 
} 

這是我思考中的最佳解決方案。但是,您可以創建一個NSTimer,它可以在一段合理的時間內執行一個方法,您可以在其中保存和保存上下文。

您還可以保存在AppDelegate中的方法,就像您的上下文(如果您指定的iOS 4.0及以上,如果你的應用程序是通過iOS的它自身的一些原因退出),

- (void)applicationWillTerminate:(UIApplication *)application{}; 

以下方法將總是打電話的時候,你的應用程序進入後臺,

- (void)applicationDidEnterBackground:(UIApplication *)application{}; 
+0

但是,如果應用崩潰,它也會沖刷核心數據。 – Mann 2015-03-19 09:52:11

+2

這是壞的。你應該*不*在任何地方使用'try catch'!這是Objective-C而不是Java! iOS上的例外總是意味着致命的,請閱讀此長時間的Apple員工和開發人員的更多信息:http://stackoverflow.com/questions/3378696/iphone-try-end-try/3379240#3379240 – Kerni 2015-03-19 12:05:28

+0

@Kerni好點,我已經更新了我的答案。請檢查一次。謝謝。請讓我知道是否仍需要更新。 – Hemang 2015-03-19 13:29:54

-1

使用

  • (無效)applicationWillTerminate:(UIApplic應用程序

AppDelgate委託方法將您的數據保存在覈心數據中。

+0

這不起作用。如果發生崩潰,它們將不會被調用! – Kerni 2015-03-19 12:03:59

0

您可以實現一個HandleException來捕獲所有異常,使應用程序崩潰。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    //for uncaughted exceptions 
    NSSetUncaughtExceptionHandler(&HandleException); 

    struct sigaction signalAction; 
    memset(&signalAction, 0, sizeof(signalAction)); 
    signalAction.sa_handler = &HandleSignal; 

    sigaction(SIGABRT, &signalAction, NULL); 
    sigaction(SIGILL, &signalAction, NULL); 
    sigaction(SIGBUS, &signalAction, NULL); 
    //and more if you need to handle more signals  


    //another setup ... 
    return YES 
} 

#pragma mark crash management 
void HandleException(NSException *exception) { 
    NSLog(@"[FALTAL] App crashing with exception: %@", exception); 
    //try to save your DB here. 
} 

void HandleSignal(int signal) { 
    //try to save your DB here. 
} 

#pragma - 

但是,我不知道應用程序退出之前您將擁有多少時間。但我想你會有足夠的時間來完成數據庫備份任務。

+0

但是,如果應用崩潰,它也會沖刷核心數據。我怎樣才能保持活着 – Mann 2015-03-19 09:52:31

+0

這是行不通的。如果發生崩潰,它們將不會被調用! – Kerni 2015-03-19 12:03:51

+0

我更新了我的答案。 – 2015-03-19 13:25:59