1

我正在使用GCD啓動一個創建NSManagedObjectContext('MOC')的長時間運行的後臺進程('run_loop'),監視CoreData對象,有時(準備好的時候)將它們的序列化上傳到一個web服務器然後刪除它們。CoreData與GCD隊列中的AFNetworking請求不兼容?

我正在使用AFNetworking進行HTTP調用。問題在於請求完成處理程序塊中,因爲這些塊在與MOC的所有者不同的線程中運行,而CoreData不支持該線程。

我已經嘗試從GCD run_loop塊的開始存儲NSThread,並使用performSelector:onThread:run_thread,但這似乎並沒有真正調用選擇器。

我試過使用dispatch_sync(run_queue),但是這並不能保證線程是一樣的,只有GCD隊列。主線程中保存的另一個MOC稍後掛起。

最終,唯一有效的工作是在完成回調處理程序中設置布爾值,並引入額外的邏輯來檢測布爾開關並從主run_loop執行MOC工作。

任何人都可以建議一個更優雅的修復?或者CoreData與從GCD隊列啓動的AFNetworking請求不兼容,我應該從頭看一下低級別的線程控制?

回答

0

嗯..處理MOC和線程的推薦方法是始終創建一個新的MOC,它是主線程MOC的子moc。讓主線程完成所有的保存,但是你的GCD線程基本上可以將更改合併到主MOC中。

我和https://github.com/magicalpanda/MagicalRecord/一起工作得非常成功,以更簡單的方式促進這一點。

+0

謝謝!我現在在完成隊列中創建第二個MOC,每次調用它時,我都按照http://stackoverflow.com/questions/6959225/core-data-merge-two-managed-object中所述設置了合併-context - 這很好用! – cachvico 2012-07-11 08:58:58

+0

它有效,但它對我來說仍然不太合理。我在一個調度隊列上創建了主MOC,因此使用[moc performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification)]看起來不是正確的(當然,mergeChanges ..調用應該在後臺線程而不是主線程上運行? )我試着將它切換到[moc performSelector:onThread:run_thread,但這也不起作用,它只是掛起。 – cachvico 2012-07-11 16:34:24

+0

GCD是一個奇怪的野獸,取決於需要什麼,你的塊可以在任何地方運行,同步分派塊實際上在主線程上運行,異步塊在任何可用線程上運行。你實際上必須在處理回調或調度的任何地方使用臨時MOC。 – piotrb 2012-07-26 22:33:44