2016-07-22 116 views
0

問題陳述

我有麻煩保存服務器端數據異步IOS核心數據異步節約

結構

我使用的NSManagedObjectContext以下結構的父母爲了孩子:

  1. writerManagedObjectContext(NSPrivateQueueConcurrencyType)
  2. masterManagedObjectContext(NSMainQueueConcurrencyType)
  3. backgroundManagedObjectContext(NSPrivateQueueConcurrencyType)

我使用下面的代碼保存數據

[backgroundManagedObjectContext performBlock:^{ 
    [backgroundManagedObjectContext save:nil]; 
    [masterManagedObjectContext performBlock:^{ // Starts blocking UI from here 
     [masterManagedObjectContext save:nil]; 
     [writerManagedObjectContext performBlock:^{ 
      [writerManagedObjectContext save:nil]; 
     }] 
    }] 
}] 

問題

代碼節省精碼。 backgroundManagedObjectContext也異步保存。但是,masterManagedObjectContextwriterManagedObjectContext都拒絕異步保存並阻止UI線程。 (我知道它會阻止UI線程,因爲我嘗試執行裏面什麼都沒有做與核心數據的行爲,他們也被封鎖,這不是不是持續協調訪問的情況下)

問題

  1. 上述代碼阻塞主線程的原因是什麼?
  2. 我是否正確假設我可以從任何地方調用上述代碼,因爲save將在每個相應的線程/上下文中調用?

任何幫助將不勝感激。

編輯

http://floriankugler.com/2013/04/29/concurrent-core-data-stack-performance-shootout/

顯然凍結來源於試圖傳播到父的NSManagedObjectContext。這篇文章似乎避免了這樣一個事實,即不可能對主要上下文進行真正的異步保存。

數據被嚴重鏈接,5MB,大約需要40s才能保存到psc。我不認爲我會使用後面描述的並行結構,因爲代碼庫已經很大。我將不勝感激任何可以用來減少這種凍結的策略。

回答

1

即使backgroundManagedObjectContext是一個私有隊列上下文,它仍然傳播其變化高達masterManagedObjectContext,作爲其父母。這可能是它窒息的地方。合併來自子上下文的更改仍然佔用CPU時間,其效果在像UI這樣的繁忙隊列中變得更加明顯。

您可以隨時使用樂器來分析正在發生的事情。

如果您的特定使用案例允許,請嘗試將backgroundManagedObjectContext.persistentStoreCoordinator設置爲與writerManagedObjectContext相同的psc,而不是使其成爲masterManagedObjectContext的子項。

更好的是,使用像MagicalRecord這樣的真棒框架。不會讓你遠離這樣的問題,但更少的代碼使得事情(可以說)更容易調試。

+0

我已經在使用結構所示的嵌套MOC。我的問題是爲什麼儘管使用嵌套的MOC結構保存不是異步的。 – jrhee17

+0

我意識到你在重新閱讀你的文章後使用了嵌套的上下文。我會編輯我的答案。您應該避免將'nil'傳遞給'save'錯誤處理程序。你會希望能夠對錯誤做出反應。嘗試檢查錯誤,看看是否拖延你的主隊列。你也提到'服務器端'。您正在使用Core Data iCloud同步嗎? – jp2g

+0

我使用自己的服務器,但老實說服務器是無關的。基本上我解析json數據並將它們插入到Core Data中。我在做錯誤處理 - 上面的代碼只是爲了說明我的代碼是什麼樣的。 – jrhee17