2013-02-22 83 views
6

在我的應用程序中,我有UITableViewController顯示事件列表。此控制器使用ManagedObjectContext說ParentContext。現在,如果選擇了任何事件,則會顯示詳細的視圖控制器,用戶可以在其中編輯事件的詳細信息。所以,我創建了一個孩子方面說,核心數據多級父 - 子環境

ChildContext with type "NSPrivateQueueConcurrencyType"

ChildContext whose parent Context is "ParentContext".

我的代碼是:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    childContext.parentContext = self.context ; 

現在再次有一些字段和關係這需要另外的向下鑽取。所以我創造了另一種ChildContext新視圖控制器說,

GrandChildContext with type "NSPrivateQueueConcurrencyType"

GrandChildContext whose parent context is "ChildContext"

這個過程也適用於其他級別(從父(的tableView共4級)兒童)

self.context - Parent Context 
    | 
    | 
ChildContext 
    | 
    | 
GrandChildContext 
    | 
    | 
GrandGrandChildContext 

我的實體看上去像這樣

EntityA   -- (Edit View Controller - uses ChildContext) 
| 
|- Field1 
| 
|- Field2 
| 
|- RelationShip (1 to Many) - (Relationship Add/Edit View Controller - uses GrandChildContext) 
    | 
    |- Field1 
    | . 
    | . 
    |- Field3 
    | 
    |- Relationship (1 to Many) - (Relationship Add/Edit View Controller - uses GrandGrandChildContext) 
      | 
      |- Field1 
      | 
      |- Field2 

這是使用父 - 子上下文的正確方法嗎?因爲在某個時間點,我會像1 NSMainQueueConcurrencyType MOC and 3 NSPrivateQueueConcurrencyType MOC一樣。

如果不是?有沒有其他方法?

是否有太多的子上下文影響應用程序的性能?

最初我使用屬性和NSArrays來管理用戶輸入的數據,當用戶點擊完成按鈕時,我將更新/創建託管對象。但這是一個乏味的工作,它讓我的視圖控制器很髒。所以我切換到父 - 子上下文,這很容易保存/丟棄更新。

由於

回答

4

你可能已經對多個子上下文有點過分了,但只有一點兒,你的一般方法是合理的。 MOC(託管對象上下文)是一個相當輕量級的對象。

我喜歡你的方法,在每個視圖控制器/場景中有獨特的參考,適用於該場景的MOC。

將MOC視爲會話或暫存區有時很有幫助。對決不在MOC和實體之間,而是在MOC和邏輯工作單元之間。

如果您的一個向下鑽取標記了用戶可能想要放棄/取消的某個編輯任務的開始,那麼這是一個剝離子MOC並將其傳遞給新視圖的好時機。如果需要的話,你可以回滾:甚至放棄MOC,當你放鬆回到起點時。另一方面,如果您只是爲靜態信息編寫一個查看器,則只需使用一個MOC。在這種情況下,沒有必要或從中獲益更多。

+3

在所有的演習中,我都有編輯任務。我在一些鑽取中設法減少了一些保存/取消操作。在使用此模型一段時間後,我發現的唯一問題是,創建的關係在父級子項中不可見。這隻發生在ios 5中,這是一個已知的bug,我通過在保存子上下文之前調用obtainPermanentIDs來修復它。 – krishnan 2013-04-12 01:53:14

+0

哦,我的天啊,+ krishnan,在我發現這個註釋之前,我把我的頭髮撕了一半,並嘗試添加一個acquirePermanentIDs調用。 – 2013-07-22 15:20:23

-1

或許有關於最好使用的情況下用於嵌套管理對象的上下文混亂微量。對於你的情況,我會建議只使用一個單一的上下文。

從數組等移動到核心數據是一個非常好的主意。現在釋放對象圖的真正力量和簡單性。儘量保持簡單。

爲了向下鑽取,只需將上下文傳遞給子視圖控制器。您的子視圖控制器獲取的結果控制器可以使用與父視圖控制器相同的上下文。衆多Apple代碼示例正是使用這種模式。

您需要上下文的唯一時間是如果您確實需要併發性。這似乎並不是這種情況。一旦檢索到數據,就會顯示子視圖控制器的新界面。如果這需要很長時間(比如說,因爲數據來自Web服務),那麼您將顯示某種「請稍候」界面,並在數據檢索完成後顯示完整的界面。很可能這不是你的情況。

+5

如果您查看[link](https://developer.apple.com/videos/wwdc/2012/)wwdc 2012視頻核心數據最佳做法會話214,它將顯示如何使用父級和子級上下文顯示詳細信息視圖控制器。我正在使用相同的技術,所以如果用戶點擊保存按鈕,我可以保存子上下文,並且子上下文的所有更改都會被推送到父上下文。當用戶點擊取消按鈕時,我只需關閉視圖控制器,所有更改都將丟失。這裏我所有的子視圖控制器都是詳細檢查器,它使用編輯數據,所以沒有提取結果控制器。 – krishnan 2013-02-23 02:07:19

+0

您可以使用'[上下文回滾];''而不是'[context save:nil];''來實現同一個上下文。如果詳細視圖控制器的提取會花費過多的時間,則WWDC視頻非常有用。 – Mundi 2013-02-23 19:05:58

+0

我想你不理解我的問題。我的問題是類似這[一](http://stackoverflow.com/questions/10443754/undo-all-changes-made-in-the-child-view-controller)。但在我的情況下,我有多層次的兒童情況。用'[上下文回滾]'我所有的更改都將丟失。但是,我只想要放棄一些更改。我會盡快上傳一個示例項目。謝謝 – krishnan 2013-02-24 05:46:39