2010-06-05 83 views
0

另一天,另一個CoreData問題......但希望現在是最後一個。向CoreData App添加新對象時出現問題

確定這裏是什麼,我有一個副本:

我有酒店的客人是停留在一個房間,並有偏好的列表。一旦準備就緒,用戶應該選擇一個訪客並查看數據,並且還應該能夠添加新的訪客,選擇房間(也由應用程序維護)並選擇他們的偏好(用戶也可以添加新的偏好)。客人可以沒有或有很多偏好。

所以這裏是我到目前爲止。我創建了3個實體: - 具有roomnumber的房間 - 具有名稱的首選項 - 具有名稱的GuestInfo - >與這些關係室(目的地房間)和首選項(具有「多對多關係」的目的地首選項)當您創建託管對象類。

現在我創建了一個UITableViewController來顯示所有的數據。我也有一個編輯和添加模式。當我添加一個新的Guest,並填寫名稱時,一切正常。但是,當我要添加的首選項或房間號我得到這個錯誤:

非法嘗試建立在不同的上下文

現在對象之間的關係「房間」,是什麼讓我困惑的是,當我添加一個客人,輸入名字,保存,回去編輯並選擇它的工作原理和房間號碼?

我有兩個ViewControllers此行選擇的房間或首選項:

[editedObject setValue:selectedRoom forKey:editedFieldKey]; 

這個.H:

NSManagedObject *editedObject; 
NSString *editedFieldKey; 
NSString *editedFieldName; 

再次,它的工作原理上的編輯模式,但不是當我想添加一個新的對象。

而且可以肯定的,這就是我對加入新的客戶做:

- (IBAction)addNewItem 
{ 

    AddViewController *addViewController = [[AddViewController alloc] initWithStyle:UITableViewStyleGrouped]; 
    addViewController.delegate = self; 
    addViewController.context = _context; 

    // Create a new managed object context for the new book -- set its persistent store coordinator to the same as that from the fetched results controller's context. 
    NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] init]; 
    self.addingManagedObjectContext = addingContext; 
    [addingContext release]; 

    [addingManagedObjectContext setPersistentStoreCoordinator:[[_fetchedResultsController managedObjectContext] persistentStoreCoordinator]]; 

    GuestInfo *info = (GuestInfo *)[NSEntityDescription insertNewObjectForEntityForName:@"GuestInfo" inManagedObjectContext:addingContext]; 

    addViewController.info = info; 

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addViewController]; 

    [self.navigationController presentModalViewController:navController animated:YES]; 

    [addViewController release]; 
    [navController release]; 
} 

任何我所要做的初始化房或偏好設置? 希望有人能幫助我。謝謝

回答

2

您遇到的問題嚴重與您的(錯誤)使用NSManagedObjectContext對象有關。基本上,您不能使用兩個不同的託管對象上下文來建立由_context管理的對象與另一個由addingContext管理的對象之間的關係。創建一個新的NSManagedObjectContext並將其傳遞給視圖控制器以便在堆棧中進行推送僅適用於要向該上下文添加新對象的情況,而不適用於要在屬於不同NSManagedObjectContext對象的對象之間建立關係的情況。

這就是爲什麼您會收到消息「非法嘗試在不同上下文中的對象之間建立關係」空間「。要解決這個問題,請使用_context對象來創建並保存新對象。

+1

我剛纔寫了一個類似的答案。我唯一要補充的是,它可以幫助海報在選中Core Data選項的情況下創建iPhone/iPad項目模板。該模板顯示瞭如何在App委託中設置核心數據堆棧,並將NSManagedObjectContext交給頂層(根)視圖控制器 - 然後將其交給它推送的各種視圖控制器。 MOC只應創建一次(如您所述)。 +1 – 2010-06-05 16:36:22

+1

感謝您的信息,我只是通過使用_context嘗試了這一點,但這並沒有奏效。目前正在運行的是我實際上只是使用addsContext,但我不確定爲什麼,因爲這看起來不正確。你能給我更多的細節,我應該如何使用_context或發佈addNewItem的rewirte?非常感謝 – elementsense 2010-06-05 16:57:47

+0

正如Matt所建議的那樣,查看標準源代碼來初始化Core Data堆棧,並將初始化的上下文正確地傳遞給您的根視圖控制器。然後,要添加新項目,請創建新項目,分配並初始化添加控制器,並最終將創建的上下文和項目傳遞給新控制器。將控制器放在堆棧上並根據需要作出反應:如果用戶想要保存該項目,則保存該項目;否則,通過刪除它並保存上下文來放棄您創建的項目。上下文和項目都是添加控制器的屬性。 – 2010-06-06 06:57:18

1

不要創建新的上下文。您必須使用之前創建房間的相同上下文。爲什麼每次添加新項目時都會創建新的上下文?這就是你得到錯誤的原因。除非你有線程問題,否則你應該在應用程序啓動或加載數據時創建一個上下文,然後在整個過程中使用它。即使有線程問題,通常每個線程只應有一個上下文(或每個臨時數據集至少有一個上下文)。

+2

該問題與使用新的上下文無關;它與嘗試建立屬於不同上下文的對象之間的關係有關。每次創建一個新的上下文是完全可行的,如果要創建的對象足夠簡單,這也是標準做法。爲什麼?因爲如果用戶改變了自己的想法並且不想保存新對象,那麼您只需放棄新創建的上下文即可。無需刪除創建的對象。這在Apple代碼中顯示。你所說的關於線程和核心數據的所有內容對於corse來說都是真的;-) – 2010-06-06 06:52:52

+0

我確實理解這個問題,但我無法得到針對此問題的實際解決方案。我有一個部分工作的解決方案,允許我添加新的項目,包括相關的詳細信息,但如果我按取消,我剩下一個空的記錄,我不知道如何刪除。 Thx順便說一句,如果你沒有提到這一點,我會根本沒有注意到。 – elementsense 2010-06-06 13:26:34

+0

要刪除您創建的新對象,您需要執行:[yourManagedObjectContext deleteObject:yourObject]; 然後,照常保存上下文。 – 2010-06-06 17:30:27