2011-08-22 116 views
0

我目前正在開發iPhone的第一個Core Data項目。經過一些實驗後,我對核心數據中的實體關係有一些相當根本的問題。如何在關係變空時刪除託管對象

假設我有兩個實體:事件和位置。他們每個人都有一個名字屬性。事件只能有一個位置,而位置可以有多個事件。因此,關係是這樣的:

Event <<--> Location 

在我的項目我(用戶)可以輸入的事件和地點的名稱。然後,我將根據該輸入爲Event實體創建一個新對象。我通過訪問事件的關係來設置位置的名稱,如下所示:

event.Location.name = someCustomString; 

保存功能可以正常工作。我認爲。

我的第一個問題是:

確實核心數據創建的地點實體的新對象每次我這樣做的時候 - 即使在同一地點的名稱已經被使用過(並仍存儲)?或者在這種情況下Core Location自動只設置與現有Location對象的關係?因爲我的項目有必要識別發生在同一地點的事件。

這也使我對我的下一個問題:

有關刪除事件對象是什麼?當我這樣做時,我必須檢查相應的位置是否被多個事件使用。如果是這樣,我將取消關係,但保留Location對象。如果不是,我也必須刪除Location對象。我目前的做法(基於我的假設,即具有相同名稱的位置沒有得到雙重保存)看起來是這樣的:

Event *event = (event *)[appManager.results.fetchedObjects objectAtIndex:indexPath.row]; 

    NSInteger locationEvents = 0; 

    for (Event *eve in appManager.results.fetchedObjects) 
    { 
     if (eve.Location.name == event.Location.name) 
     { 
      locationMoments++; 
     } 
    } 

    if (locationMoments == 1) 
    { 
     [appManager.managedObjectContext deleteObject:event.Location]; 
    } 

    [appManager.managedObjectContext deleteObject:event]; 

所以,至少我覺得我檢查事件的數量是一定的位置對象是指。但代碼感覺有點癢......我不知道這是否正確。所以我最後的問題是: 我的方案中的標準程序是什麼?如果有的話。 ;)

謝謝大家提前你的答案!

回答

0

確實核心數據創建新對象的位置實體每次 我做這個

沒有,event.Location.name是「走」,從Event實例的Location實例的關係的keyPath然後訪問屬性name。一個關鍵路徑只適用於一個現有的對象。

不過,既然你有一個Location對象有許多Event對象共享,任何一個Event對象改變Location.name值更改爲共享Location對象的所有Event對象的值。

如果您希望託管對象在關係變爲空時立即刪除自己,請將刪除代碼放入該類的remove…訪問器方法中。當關系達到零時,讓對象告訴上下文將其刪除。這可以讓你把代碼放在一個地方,而不是分散在任何可能改變關係的地方。

如果您只想在保存上下文時刪除對象,請將代碼放在類'willSave方法中。這將在下一次保存上下文時觸發刪除。

+0

你說一個關鍵路徑只適用於現有的對象。但是,當我創建一個事件並首次使用該事件的位置名稱時 - 必須創建一個新的位置對象,不是嗎?從那一刻起,具有相同Location.name的事件會自動分享它?只是問問。我真的很想知道發生了什麼。 :)你在空關係上刪除Location對象的方法聽起來是對的。我必須考慮這一點!我的代碼樣本是否符合要求?或者你通常如何在這種情況下檢查現有關係?非常感謝您的回答! – Leakazoid

+0

創建'Event'對象不會自動創建'Location'對象,它只會在'Event'對象中創建一個空的'Event.location'屬性。您必須爲該關係分配新的或現有的「位置」對象。要檢查一個空關係,只需計算對象的數量,例如'[self.location count] == 0' – TechZen

+0

好吧,我現在明白了。現在我也意識到問題是我保存實體的方式。每當創建一個新的Event對象時,我正在創建一個新的Location對象。 (思想核心數據可能會自動檢查重複項。)相反,我應該檢查一個現有的位置對象,它可能包含與當前輸入的名稱相同的名稱。然後我將它鏈接到我的新活動。我必須爲此目的創建一個位置對象的獲取請求,並帶有謂詞,對吧? ...再次感謝您的幫助,TechZen! – Leakazoid

0

非常感謝您的幫助TechZen。現在我認爲我更瞭解Core Data。而且我還有我的數據模型工作。原來,當我創建我的實體和適當的子類時,我忘了將實體的類設置爲檢查器中創建的文件。 (認爲​​這會自動設置 - 因爲文件也是自動創建的。)因此,我的Location實體的willSave方法從未被調用過。我解決了這個問題,並解決了如何以正確的方式處理關係。正如我所說的,我用一個簡單的「name ==%@」謂詞使用了一個獲取請求來查找以前使用的位置名稱。 ;)

但畢竟我也使用實際位置數據(緯度,經度)。即使位置和名稱相同,位置的座標也會略有不同。所以我必須找到一種方法來比較存儲的座標和當前用戶位置的座標。當用戶靠近先前使用的位置並使用該名稱時 - 那麼新的座標數據應該覆蓋舊的位置 - 或者它應該放在一邊,並且新事件被賦予舊位置。如果你對此有任何想法,我也會很感激!但我想我知道該怎麼做 - 主要是。 :)

相關問題