2010-08-12 39 views
6

我有關於核心數據的一些基本問題(我是新來的),我希望對當前的標準和實現有一些看法。關於典型用法的核心數據問題

基本上我有一個iPhone上的應用程序(支持iOS 3.0及以上版本),它通過HTTP從Web調用獲取大量數據,我正在將結果移動到本地存儲中,以便用戶下次快速檢索再次加載相同的數據(數據不會改變,這就是爲什麼我可以依賴緩存版本是準確的)。

我只是想先知道的幾件事:

  1. 難道人們這些天治療延伸NSManagedObject作爲領域對象,還是你嚴格創建單獨的類別進行存儲和創建的helper方法管理對象創建它們到域對象?我有時會發現將所有持久性邏輯放在域外是一件好事。

  2. 如何清理?如何在應用程序關閉時刪除所有數據,或者可能會在本地存儲中刪除數據?我當然不想在用戶手機上隨時保存數據。

  3. 核心數據是否有任何類型的原子性?我的實現將首先在本地檢查Web服務之前檢查數據,我想確保從未有一半數據集被提交到本地存儲並獲得有趣的結果。

  4. 我想運行一個公平的後臺線程來獲取背景中的數據,有什麼事情我需要考慮什麼時候在後臺線程上持久化對象?

  5. 關於上述問題,創建「後臺讀取」循環的最佳方法是什麼?在應用程序委託?每個視圖,取決於視圖?等等...?

我希望這些都不是太基本:)

感謝所有幫助你可以給。

回答

5

人做這些天治療管理 對象擴展NSManagedObject作爲 域對象,還是你創建 單獨的類嚴格用於存儲 和創建的helper方法來創建 他們到域對象?我有時 發現保持所有持久性邏輯出 該域名是一件好事。

如果您創建完全獨立的域對象,你必須讓他們同步你的核心數據模型,並保持核心數據和工作與這些對象之間的轉換成本 - 加上你在內存中重複的對象,這取決於你有多少物體可能是一個問題。

但是,使用單獨的域對象的好處是您不再被固定到託管對象上下文。一種情況是,如果您維護對託管對象的引用,然後某些後臺操作導致主要託管對象上下文刪除對象 - 現在如果您訪問刪除的託管對象中的任何屬性,則會觸發故障異常(即使你明確地加載了沒有錯誤數據的對象)。

我曾嘗試過適度成功的一件事是偶爾爲特定用途使用非常輕量級的單獨數據對象 - 我所做的是定義一個協議來表示數據對象訪問器,並使用與核心數據訪問器相同的名稱。然後我有核心數據對象和一個自定義獨立數據對象實現這個協議,並有一個機制來自動地將屬性從一個複製到另一個。所以我沒有將每個對象都做成自定義的,並且可以將來自本地商店的對象或獨立對象替換爲對象。

我沒有明確的偏好,但仍偏向直接使用託管對象,因爲缺少重複。您可以通過監聽更改或使用核心數據控制器類來減輕不良的副作用。

有一件事情,有助於保持域對象和數據對象排序相同但不是,使用mogenerator生成數據對象。它會生成核心數據存儲中對象的非常好的對象表示,以及要編輯的前端對象 - 向其添加自定義訪問器或複雜方法。更改數據存儲mogenerator重新生成數據對象,但只保留自定義代碼。

http://rentzsch.github.com/mogenerator/

怎麼樣清理?一個 通常會在 應用程序關閉時刪除所有數據,或者可能會在 中刪除本地存儲中的數據?我當然不想 在任何時候都想要在用戶手機上保存數據。

數據通常足夠小,我只是將它留在那裏,並使用過期時間戳,以便您知道數據太舊而無法直接使用。由於用戶頻繁關閉和重新打開應用程序,因此保存數據的價值非常高,並且已經有數據,您可以在獲取內容更新時立即呈現結果。

是否有任何類型的原子與 核心數據?我的實現將 首先檢查本地數據在 擊中網絡服務之前,我想 確保從未有一半數據集被提交到本地 存儲並得到有趣的結果。

原子性來自於您在上下文中執行操作,然後告訴上下文保存。所以真正的原子性意味着在你準備好之前避免其他組件發出一個保存,這通常意味着在自己的上下文中做一些事情併合並回主環境中。

我想運行一個公平的幾個 後臺線程在 取數據的背景,是否有在後臺線程持續 對象時,我 需要考慮任何事情?

每個後臺線程都需要自己的上下文,您應該聽取保存通知併合併到當前的主上下文中。

您應該努力避免可能幾乎同時保存到同一對象的重複請求,這有時會導致合併時出現核心數據錯誤。與此相關 - 在主要上下文中設置合併策略,因爲默認策略是拋出異常。

這也意味着在建模過程中,儘可能多地使用單獨的對象,而不是聚集來自許多不同來源的數據的一個大對象。

有關保存與合併到其他環境中的更多信息,請參見該問題:

CoreData and mergeChangesFromContextDidSaveNotification

關於上述問題, 什麼是創建一個 「背景獲取的最佳途徑「循環?在應用程序 委託?每個視圖取決於 視圖?等等...?

我想從一個單獨的單例類做到這一點(畢竟AppDelegate中本身就是一個單...),我可以在另外索要主要管理對象上下文具體到一個線程上下文。

這在啓動新的Core Data項目時也很有用,您不必使用Core Data模板,只需重新使用此核心數據管理器即可。

+0

首先,感謝您花時間回答您的問題,+1爲詳細信息。我只有幾個後續問題,1.您能否詳細解釋一下原子性?我只是沒有真正關注你。 2.你提到了一個主背景,並且合併,我不熟悉這些,你是否也可以詳細說明這些? 3.你如何管理每個線程的不同上下文?是否只是在創建線程時獲取上下文的問題,然後一旦線程完成將該上下文「返回」到主線程併合並? – Mark 2010-08-12 06:29:52

+0

1)您在託管對象上執行所需的操作 - 在保存上下文之前,沒有任何更改「粘住」。擺脫上下文(或恢復更改)就像是回滾。 對於2-3 - 這個想法是,你有一個主線程的上下文。在任何後臺操作中,您都會基於同一個託管對象庫創建一個新的上下文,然後在完成編輯時保存它 - 您可以查找特殊通知,在該方法中,您可以請求合併到主上下文中。看到http://stackoverflow.com/questions/1429900/coredata-and-mergechangesfromcontextdidsvenotification – 2010-08-12 07:19:03

+0

好吧,我明白你在說什麼,再次感謝,如果你不介意我想繼續問一些更多的問題,我知道這個網站真的沒有成立討論...爲什麼你需要在NSManagedObject的屬性是@動態?如果您將它們用作域對象,那麼使用@synthesize會更容易,但是當我更改時會出現錯誤... – Mark 2010-08-12 23:14:39