簡體   English   中英

核心數據管理對象上下文設計建議

[英]Core Data managed object context design recommendation

我們正在開發一個企業級應用程序,它將使用Core Data存儲數萬個對象,並且我們在幾個方面遇到了問題。


我們的應用程序有幾個獨立的系統,可在需要時對數據進行操作 這些系統包括項目的發現,項目的加載,同步和UI顯示。 如果我們正確地設計我們的軟件,由於不同的系統修改相同的對象,應該幾乎沒有合並沖突。 每個系統都有自己的操作隊列,所有操作隊列都在后台執行。 我們希望在后台保留所有對象的創建和修改,以最大限度地減少UI性能問題,尤其是在初始加速期間,可能會從服務器上的數據創建數千個對象。 在這里,我們遇到了各種設計嘗試的幾個問題。 在這些升級期間消耗大量內存,以及所有上下文和子上下文的錯誤編排,導致死鎖和崩潰。 我們嘗試了以下設計:

  • 一個根NSPrivateQueueConcurrencyType托管對象上下文,它有一個子NSMainQueueConcurrencyType上下文。 UI獲取的結果控制器使用此子上下文從中獲取結果。 NSMainQueueConcurrencyType子上下文中,我們創建了一個NSPrivateQueueConcurrencyType子上下文,我們將其稱為“savingContext”,每個后台操作創建了一個“savingContext”的子上下文,進行了更改,最后以遞歸方式執行了我們所謂的“深度保存”保存到頂部。 我們最初選擇此設計時不必處理來自許多不同子上下文的NSManagedObjectContextDidSaveNotification通知。 我們每次調用NSPrivateQueueConcurrencyType上下文並使用performBlockAndWait:訪問對象performBlockAndWait: 功能上,這個設計執行。 所有更改和插入都保存到持久性存儲中,並且UI已根據更改進行更新。 這,介紹了兩個問題。 由於通過NSMainQueueConcurrencyType子上下文的合並更改,一個是在加速期間的NSMainQueueConcurrencyType ,更重要的是,在加速期間非常高的內存使用量。 由於無法在上下文中遞歸調用reset (因為主UI子上下文也存在)和/或缺少知識何時調用refreshObject:mergeChanges:我們會遇到禁止的RAM使用。 所以我們走了一條不同的道路。
  • 有兩個頂層環境與持久化存儲協調聯系,一個NSPrivateQueueConcurrencyType為救孩子上下文和NSMainQueueConcurrencyType UI顯示。 NSMainQueueConcurrencyType偵聽來自主NSPrivateQueueConcurrencyType上下文的NSManagedObjectContextDidSaveNotification通知,並將它們合並到主線程中。 每個后台操作都會創建主NSPrivateQueueConcurrencyType上下文的子上下文,也可以使用私有隊列並發類型,執行它的操作,遞歸執行“深度保存”,對當前上下文執行保存,對其進行深度保存的遞歸調用parent,調用當前上下文重置並再次保存。 這樣我們就可以避免內存問題,因為創建的對象在保存后會很快釋放。 但是,使用這種設計,盡管存在NSMainQueueConcurrencyType上下文的保存通知,但我們遇到了大量問題,例如NSInternalInconsistencyExceptionNSInternalInconsistencyException異常和未更新UI的獲取結果控制器。 這也會導致UI中的初始加載時間減慢很多。 在之前的設計中,獲取的結果控制器非常快地返回結果,而這會阻止UI幾秒鍾直到視圖加載(我們在viewDidLoad初始化獲取的結果控制器)。

我們已經嘗試了很多中間設計,但它們都圍繞着相同的問題,要么是非常高的內存使用率,要么取得結果控制器沒有更新UI或死鎖,以及NSInternalInconsistencyException異常。


我真的很沮喪。 我不禁覺得我們的設計對於一些應該相當簡單的事情來說是過分復雜的,只是我們缺乏理解一些殺死我們的基本因素。


那么你們會建議什么? 你會為我們的背景推薦什么安排? 我們應該如何在不同的線程中管理不同的上下文? 釋放插入對象和重置上下文的最佳實踐? 避免死鎖? 在這一點上,所有的幫助將不勝感激。


我也看到了MagicalRecords類別的建議。 推薦嗎? 我們已經投入使用核心數據類型,使用MR遷移有多難?

首先,為了管理您的內存,您的第二個架構為您提供了更大的靈活性。

其次,要管理的內存有兩種:malloc-ed內存和駐留VM內存。 您可以擁有較低的malloc內存占用空間,並且仍然具有較大的VM駐留區域。 根據我的經驗,這是因為Core Data積極地堅持新插入的項目。 我通過保存后修剪通知解決了這個問題。

第三,MOC便宜。 使用'和扔掉。 換句話說,早期和經常釋放內存。

第四,嘗試在主要的MOC上幾乎沒有任何數據基礎。 是的,這聽起來適得其反。 我的意思是所有復雜的查詢都應該在后台線程上完成,然后將結果傳遞給主線程,或者在利用現在填充的行緩存時從主線程重新執行查詢。 通過這樣做,您可以保持UI的實時性。

第五,在我的多排隊應用程序中,我嘗試將所有保存都發生在后台。 這使我的主要MOC保持快速且與來自網絡的數據一致。

第六,NSFetchedResultsController是一個非常有用但專業的控制器。 如果您的應用程序將其推送到其能力范圍之外,它將開始鎖定您的界面。 當發生這種情況時,我會通過自己監聽-didSave通知來滾動我自己的控制器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM