2012-05-27 30 views
3

使用Instruments之後,我發現我的代碼中存在很長時間的運行並阻塞了我的用戶界面:處理大量JSON數據包的一部分,建立管理對象,同時確保對象不被複制)。雖然我的意圖是將這個請求分解爲更小的部分並連續地處理它們,但這隻意味着我將分散這些提取 - 我預計效果將是應用程序中的小動作,而不是一個漫長的打嗝。使用NSOperationQueues的核心數據和併發性

我在Apple的文檔和在各種博客文章中都閱讀過的所有內容都表明,Core Data和併發性類似於戳一個蜂巢。所以,我怯怯地坐下來給大學嘗試。下面是我想到的,我會很感激有人更明智地指出我確信我寫的任何錯誤。

下面的代碼發佈作品。我讀過的東西讓我感到害怕,因爲我確實做錯了什麼;我覺得如果把手雷拔出手榴彈,我只是在等待它出乎意料!

NSBlockOperation *downloadAllObjectContainers = [NSBlockOperation blockOperationWithBlock:^{ 
    NSArray *containers = [webServiceAPI findAllObjectContainers]; 
}]; 

[downloadAllObjectContainers setCompletionBlock:^{ 

    NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [backgroundContext setPersistentStoreCoordinator:[_managedObjectContext persistentStoreCoordinator]]; 

    [[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification 
                 object:backgroundContext 
                 queue:[NSOperationQueue mainQueue] 
                usingBlock:^(NSNotification *note) { 
                 [_managedObjectContext mergeChangesFromContextDidSaveNotification:note]; 
                }]; 


     Builder *builder = [[Builder alloc] init]; 
     [builder setManagedObjectContext:backgroundContext]; 

     for (ObjectContainer *objCont in containers) { // This is the long running piece, it's roughly O(N^2) yuck! 
      [builder buildCoreDataObjectsFromContainer:objCont]; 
     } 

    NSError *backgroundContextSaveError = nil; 
    if ([backgroundContext hasChanges]) { 
     [backgroundContext save:&backgroundContextSaveError]; 
    } 
}]; 

NSOperationQueue *background = [[NSOperationQueue alloc] init]; 
[background addOperation:downloadAllObjectContainers]; 

回答

6

由於您使用NSPrivateQueueConcurrencyType你必須做它的iOS5,你不必去通過在後臺線程創建上下文並在主線程合併它的所有的麻煩。

您只需要在主線程中創建一個帶有併發類型NSPrivateQueueConcurrencyType的託管對象上下文,並在傳遞給managedObjectContext:performBlock方法的塊內執行託管對象的所有操作。

我建議你看看WWDC2011會議303 - 核心數據的新增功能iOS。 另外,請看Core Data Release Notes for iOS5

下面是從發行說明報價:

的NSManagedObjectContext現在提供了對併發操作結構化的支持。當您使用initWithConcurrencyType創建託管對象上下文時,您有三個選項用於其線程(隊列)關聯

約束(NSConfinementConcurrencyType)。

這是默認值。您承諾上下文不會被您創建它的線程以外的任何線程使用。 (這與您在以前版本中使用的線程要求完全相同。)

專用隊列(NSPrivateQueueConcurrencyType)。

上下文創建並管理專用隊列。而不是創建和管理與上下文關聯的線程或隊列,這裏上下文擁有隊列併爲您管理所有的細節(假設您使用如下所述的基於塊的方法)。

主隊列(NSMainQueueConcurrencyType)。

上下文與主隊列相關聯,因此被綁定到應用程序的事件循環中,但它與基於私有隊列的上下文相似。您使用此隊列類型來鏈接控制器和UI對象的上下文,這些對象只需要在主線程上使用。

+0

我只在iOS 5上使用它。 「核心數據併發」文章沒有提到這一點,我無法找到你在iOS 5.0 API Diffs中提出的建議。 NSManagedObjectContext的文檔對於那些常量來說有點簡潔。你能否指引我參考你參考的文檔的方向? – edelaney05

+0

當然,我編輯了原帖以解答您的評論。 – svena

0

併發

併發是在同一時間上多個隊列與所述數據進行工作的能力。如果您選擇對Core Data使用併發性,則還需要考慮應用程序環境。在大多數情況下,AppKit和UIKit不是線程安全的。特別是在OS X中,Cocoa綁定和控制器不是線程安全的。Core Data, Multithreading, and the Main Thread