objective-c - 下列哪些屬於電子商務的應用1電子拍賣2電子化政府3代客泊車4協同商務 - 電腦每次所能存取硬碟的最小區域為




每個核心數據關係都必須有一個逆向嗎? (4)

假設我有兩個實體類: SocialAppSocialAppType

SocialApp我有一個屬性: appURL和一個關係: type

SocialAppType我有三個屬性: baseURLnamefavicon

SocialApp關係type的目標是SocialApp中的單個記錄。

舉例來說,對於多個Flickr賬戶,將會有一些SocialApp記錄,每個記錄都持有一個到一個人賬戶的鏈接。 對於“Flickr”類型將有一個SocialAppType記錄,即所有SocialApp記錄都會指向該記錄。

當我使用該模式構建應用程序時,我得到一個警告,即SocialAppTypeSocialApp之間沒有反向關係。

 /Users/username/Developer/objc/TestApp/TestApp.xcdatamodel:SocialApp.type: warning: SocialApp.type -- relationship does not have an inverse

我需要反過來,為什麼?


在實踐中,我沒有任何數據丟失,因為沒有反過來 - 至少我知道這一點。 Google很快建議你應該使用它們:

相反的關係不僅使事情更加整潔,Core Data實際使用它來維護數據完整性。

- 可可開發中心

您通常應該在兩個方向上建模關係,並適當指定相反的關係。 核心數據使用此信息確保對像圖的一致性(請參閱“處理關係和對像圖完整性”)。 有關您可能不想在兩個方向上建立關係的一些原因的討論,以及一些可能會出現的問題,請參閱“單向關係”。

- 核心數據編程指南


我將解釋Dave Mark和Jeff LeMarche在“ 更多iPhone 3開發”中找到的權威答案。

Apple通常建議您始終創建並指定反轉,即使您未在應用中使用反轉關係。 出於這個原因,當你不能提供反向時,它會警告你。

關係不需要有相反的關係,因為有幾種情況,反向關係可能會影響績效。 例如,假設反比關係包含非常大量的對象。 去除反函數需要遍歷表示反轉弱性能的集合。

但是除非你有一個特定的原因不去模擬逆過程 。 它有助於核心數據確保數據完整性。 如果遇到性能問題,稍後刪除反向關係相對容易。


至少有一種情況可以在核心數據關係沒有逆轉的情況下進行良好處理:當兩個對象之間存在另一個核心數據關係時,它將處理維護對像圖。

例如,一本書包含許多頁面,而一頁則放在一本書中。 這是一種雙向多對一的關係。 刪除一個頁面只會使關係無效,而刪除一本書也會刪除該頁面。

但是,您也可能希望跟踪每本書正在閱讀的當前頁面。 這可以通過頁面上的“currentPage” 屬性完成,但您需要其他邏輯來確保書中只有一個頁面隨時被標記為當前頁面。 相反,將Book從當前頁面關係中創建為單個頁面將確保始終只有一個當前頁面被標記,並且此頁面只需book.currentPage即可輕鬆訪問該書籍。

在這種情況下,互惠關係會是什麼? 有些東西很無意義。 “myBook”或類似文件可以在其他方向上添加,但它只包含頁面“book”關係中已包含的信息,因此會產生自己的風險。 也許在將來,您使用這些關係之一的方式會發生變化,導致您的核心數據配置發生變化。 如果page.myBook已經在代碼中使用page.book的某些地方使用過,則可能會出現問題。 主動避免這種情況的另一種方法是,不要在用於訪問頁面的NSManagedObject子類中公開myBook。 然而,可以認為,首先不對倒數建模是比較簡單的。

在上面的示例中,當前頁面關係的刪除規則應設置為“無操作”或“級聯”,因為與“無效”沒有相互關係。 (Cascade意味著你在閱讀書的時候將書中的每一頁都撕掉了,但是如果你特別冷,並且需要燃料,這可能是真的。)

如果可以證明對像圖完整性沒有風險,如本例中所示,並且代碼複雜性和可維護性得到改進,那麼可以認為沒有相反的關係可能​​是正確的決定。


蘋果的文檔有一個很好的例子,表明你可能因沒有反向關係而出現問題。 讓我們將其映射到這種情況。

假設您按如下方式對其進行建模:

請注意,您有一個從SocialAppSocialAppType稱為“ type的一對一關係。 該關係是非可選的並且具有“拒絕”刪除規則

現在考慮以下幾點:

SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated

[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];
BOOL saved = [managedObjectContext save:&error];

我們期望的是會失敗此上下文保存,因為我們已將刪除規則設置為拒絕,而關係不是可選的。

但是這裡保存成功。

原因是我們沒有設定反比關係 。 因此,當appType被刪除時,socialApp實例不會被標記為已更改。 因此,在保存之前沒有對socialApp進行驗證(它假定沒有需要驗證,因為沒有發生變化)。 但實際上發生了變化。 但它沒有得到體現。

如果我們回想一下appType

SocialAppType *appType = [socialApp socialAppType];

appType是零。

奇怪,不是嗎? 對於非可選屬性,我們得到零嗎?

所以,如果你建立了反向關係,你就沒有麻煩了。 否則,您必須通過編寫代碼進行強制驗證,如下所示。

SocialApp *socialApp;
SocialAppType *appType;
// assume entity instances correctly instantiated

[socialApp setSocialAppType:appType];
[managedObjectContext deleteObject:appType];

[socialApp setValue:nil forKey:@"socialAppType"]
BOOL saved = [managedObjectContext save:&error];