2012-05-03 29 views
3

我有一個應用程序,可以在用戶明確按下同步按鈕後從Web導入潛在的大量數據,並使用核心數據存儲該數據。由於我想顯示反饋,並且我不希望用戶在發生這種情況時與應用程序的其餘部分進行交互,因此按下「同步」按鈕將彈出一個「模式」對話框。由於我希望操作立即發生,操作在viewDidAppear方法中執行。我敢肯定這是令人不悅的。使用核心數據的長時間運行的前臺操作的最佳做​​法?

有一堆與方法問題現在:

  • 一切都發生在主線程。用戶類型獲得反饋是因爲有一個活動指示器繼續動畫,但無法指示進度或顯示中間消息。這不是正確的做事方式。
    • 但是,我被告知,使用核心數據時,一切都必須使用主線程,因此將工作分解到另一個線程似乎不會很簡單。
  • 如果應用程序進入後臺狀態(用戶點擊主頁按鈕或iPad進入睡眠狀態),遊戲結束 - 操作失敗。從文檔來看,我很清楚爲什麼會出現這種情況。
    • 我知道有「我即將進入後臺」事件,你可以處理,但它不像我可以在一個文件下載中移動代碼從一個地方執行到另一個地方。無論我使用哪種解決方案,都必須是一種連續的操作,在轉換到/從後臺轉換之前和之後以相同的方式執行。
    • 我希望操作在用戶所關注的前臺執行。在此操作發生時,他們與應用程序的其他部分進行交互沒有任何意義。

我讀這個蘋果的文檔,但我問這在需求這一特定組合尋找更簡潔指導的希望。謝謝。

+0

您關於需要主線程的核心數據的陳述不正確。請閱讀併發部分:https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html –

+0

@T雷迪你是對的。我的聲明只有在我嘗試將主線程的託管對象上下文傳遞給工作線程時纔是真實的。如果我在工作線程中創建了一個新的託管對象上下文,那麼這是受支持的(我只需要確保我做了一些事情,讓主線程的管理對象上下文知道工作者上下文所做的更改)。 –

+0

不僅僅是上下文,但任何託管對象都不能跨越線程邊界。我已經使用這個託管對象包裝器來簡化核心數據文檔概述的線程需求:https://github.com/chriscdn/RHManagedObject –

回答

2

你真的不應該凍結主線程。您仍然可以「禁止」某些用戶界面操作。

創建一個單獨的上下文,作爲一個孩子,並在那裏做所有的工作。完成後(或者在一定的時間間隔),保存上下文的主要方面,並通知主線程做一些UI更新交互...也許一個進度條或東西...事情

NSManagedContext *backgroundContext = [NSManagedContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
backgroudContext.parentContext = [self mainManagedObjectContext]; 
[backgroundContext performBlock:^{ 
    // This block is running in a background thread. 
    // Go get your data from the web 

    // Call this to push data to the main MOC (either at end, or at intervals) 
    [backgroundContext save:&error]; 

    // When you want to do something on the main thread... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // This block is running on the main queue... I can do anything with the UI... 
    }]; 
}]; 

夫婦注意...你的mainMOC需要是私有的或主隊列併發類型。如果您使用Core Data模板,它在應用程序委託中的位置,只需將alloc/init更改爲initWithConcurrencyType:NSMainQueueConcurrencyType。

但是,我會建議使用規範的主/父關係。創建一個私有MOC,將其分配給持久性存儲,然後創建一個主MOC,將其父級設置爲該私有MOC。現在您已準備好處理任何具有後臺操作的I/O,而不會阻止您的用戶界面。

不過,從Web上加載時,請使用上面的模式:創建一個子MOC,然後將對象加載到主MOC中。

請注意,在「根」MOC調用保存之前,數據不會保存到磁盤。

相關問題