我正在使用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請求不兼容,我應該從頭看一下低級別的線程控制?
謝謝!我現在在完成隊列中創建第二個MOC,每次調用它時,我都按照http://stackoverflow.com/questions/6959225/core-data-merge-two-managed-object中所述設置了合併-context - 這很好用! – cachvico 2012-07-11 08:58:58
它有效,但它對我來說仍然不太合理。我在一個調度隊列上創建了主MOC,因此使用[moc performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification)]看起來不是正確的(當然,mergeChanges ..調用應該在後臺線程而不是主線程上運行? )我試着將它切換到[moc performSelector:onThread:run_thread,但這也不起作用,它只是掛起。 – cachvico 2012-07-11 16:34:24
GCD是一個奇怪的野獸,取決於需要什麼,你的塊可以在任何地方運行,同步分派塊實際上在主線程上運行,異步塊在任何可用線程上運行。你實際上必須在處理回調或調度的任何地方使用臨時MOC。 – piotrb 2012-07-26 22:33:44