0

執行節能我迷上了一個NSFetchedResultsController表視圖,以及相應的managedObjectContext是self.myDatabase.managedObjectContext:UIManagedDocument:如何在後臺

self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request 
                    managedObjectContext:self.myDatabase.managedObjectContext 
                     sectionNameKeyPath:nil 
                       cacheName:nil]; 

現在,每當用戶刷新我執行該頁面下面的代碼。從本質上說,我創建了一個新的線程來加載數據,然後更新/保存新的數據對MOC-安全線:

dispatch_queue_t fetchQ = dispatch_queue_create("fetcher", NULL); 
dispatch_async(fetchQ, ^{   
    NSArray *data = [MyAPI myData]; 

    [document.managedObjectContext performBlock:^{ 
     for (NSDictionary *info in data) { 
      [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:self.myDatabase.managedObjectContext]; 
     } 
    }]; 
}); 
dispatch_release(fetchQ); 

這工作得很好:我讓我的更新和表視圖正確顯示一切。唯一的問題是UI沒有響應,大概是因爲我在主線程上進行了保存/更新。所以,我看着這個修改後臺線程執行它:

NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] init WithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    [backgroundContext setParentContext:self.myDatabase.managedObjectContext]; 

    [backgroundContext performBlock:^{  
     NSArray *data = [MyAPI myData]; 

     for (NSDictionary *info in data) { 
      [MyEntity createOrUpdateGivenInfo:info andManagedObjectContext:backgroundContext]; 
     } 

     [backgroundContext save:nil]; 

     [document.managedObjectContext performBlock:^{ 
     [document updateChangeCount:UIDocumentChangeDone]; 
     }]; 
    }]; 

然而,雖然UI現在是有求必應,我得到麻煩的負載與表視圖:而不是更新現有條目,該表顯示一個額外的條目(一個不應該存在的副本)。我認爲這可能是因爲這兩個競爭對手沒有同步/合併,但是從閱讀之前的SO帖子,我被認爲只需要調用saveContext然後在主MOC上調用updateChangeCount。 如果我重新啓動應用程序,一切再次正常工作 - 直到我再次刷新。

有沒有人有任何幫助。我從字面上開始拉我的頭髮。

我會給你啤酒,如果你能解決這個謎。

+0

處理背景上下文的一般想法是正確的。請發佈您的代碼爲createOrUpdateGivenInfo:andManagedObjectContext:噢是的...也爲您的NSFetchRequest和NSFetchedResultsController的設置 - 聽起來像你可能無法正確獲取或處理合並。 – 2012-07-10 17:13:48

回答

2

UIManagedDocument爲您創建兩個上下文:NSPrivateQueueConcurrencyType的根上下文和NSMainQueueConcurrencyType的子上下文。

將您的NSFetchedResultsController連接到document.managedObjectContext,因爲這是您主線程的上下文。

讀取/寫入發生自動在後臺線程上。 UIManagedDocument照顧到這一點。你不必擔心。

如果您需要自己做一些繁重的工作,您可以創建另一個管理對象NSMainQueueConcurrencyType並將其設爲document.managedObjectContext的父項。

我看了你的代碼,它看起來像這是你做的,這應該工作。這正是我在應用程序中所做的。但我看到其他幾個人報告重複條目NSFetchedResultsController懷疑存在框架錯誤。

如果你願意分享你的項目,我會看看。