2012-04-17 42 views
6

考慮以下簡單的實體模型:實體A具有對一關係到實體B稱爲b。實體B具有稱爲a的相反關係。這兩種關係都不是可選的。關係完整性和驗證在覈心數據的iCloud同步處理

A   B 
b < ----- > a 

假設我們有兩個設備(1)和(2)開始完全同步。每個都有一個A類對象和一個B類對象,並且它們相互關聯。在設備1上,我們有對象A1和B1,在設備B上我們有相同的邏輯對象A1和B1。

現在假設simulateous改變每個器件上製成:

在裝置1中,我們刪除B1,B2插入,和準A1與B2。然後 保存更改。
在設備2上,我們刪除B1,插入B3,並將A1 與B3關聯。然後保存更改。

設備1現在嘗試從設備2導入事務日誌.B3將被插入,並且A1將與B3關聯。到目前爲止這麼好,但B2現在剩下關係a等於的關係是非可選的,所以發生驗證錯誤。

類似的東西將發生在裝置2中,因爲有兩個B的物體,並且只有一個目的要與之關聯。必有從而始終是一個驗證錯誤,因爲乙對象中的一個必須具有關係設定爲

更糟糕的是,任何未來的變化將永遠留下一個錯誤的對象B遊逛,因此將無法通過驗證。實際上,用戶不能通過重新設置關係來解決問題。它永久破碎。

問題是,你怎麼能解決這樣的驗證錯誤?這一切都發生在NSPersistentStoreDidImportUbiquitousContentChangesNotification通知被觸發之前。這不是您的應用主NSManagedObjectContext中的驗證錯誤,它是在將事務日誌初次導入持久性存儲過程中發生的驗證錯誤。

我能想到的唯一選擇可能是嘗試刪除B類本身上的自定義設置器(setA:)或KVC驗證方法(validateA:error:)中的無效B對象,因爲它們似乎是在事務日誌導入期間觸發。但我不確定這樣的副作用是否被允許,當我嘗試它時,它似乎會導致令人討厭的日誌消息。

任何人都知道正確的處理方法是什麼?

回答

2

退房此線程蘋果的開發者論壇:

https://devforums.apple.com/message/641930#641930

有來自蘋果員工的響應。簡而言之:

1)這是在覈心數據的iCloud已知錯誤的iOS(5.1)和OS X(10.7.3)的當前版本下同步。

2)如果關係對於驗證謂詞是非可選的,則同步將完全停止。所以你需要刪除驗證的時間來保持事情的順利進行。但是,這樣做會使設備的數據不匹配。

3)沒有官方的解決方法。一種混亂的方法是維護一個跟蹤關係的單獨屬性。然後,您需要掃描通過iCloud更改的任何對象,並修復該關係(如果爲零)。

我也被這個bug咬了。處理遇到麻煩的顧客非常沮喪。希望蘋果的修復很快就會出來......

+0

謝謝,這非常有用。開發論壇帖子似乎表明這只是一對多關係的問題,但我不認爲是這樣。它會在任何需要的關係被同時修改的情況下出現。無論如何,至少我知道這是一個框架中的錯誤,並且可以嘗試解決它。 – 2012-04-18 09:04:38

+0

這個問題在6.x和10.8.x中是否仍然存在? – 2013-02-18 14:44:39

+0

不幸的是,它仍然是iOS 6.1中的一個問題。 – thevoid 2013-02-18 18:45:22

1

如果這有助於他人,我已經在iCloud中繞過這個bug取得了一些進展。我所做的是在初始事務日誌導入期間禁用驗證,並在我的MOC保存到我的主存儲時再次啓用它。當然,我仍然遇到驗證錯誤,但它們發生在我的MOC保存方法中,而不是深入到Core Data框架中,因此我可以修復錯誤(例如,刪除無效對象)。

如何禁用驗證?我這樣做的方式是覆蓋NSManagedObject子類中的KVC驗證方法,該子類已用作所有Core Data實體類的根類。

-(BOOL)validateValue:(__autoreleasing id *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error 
{ 
    if (![self.managedObjectContext isKindOfClass:[MCManagedObjectContext class]]) { 
     return YES; 
    } 
    else { 
     return [super validateValue:value forKey:key error:error]; 
    } 
} 

在重寫,我檢查類的管理對象上下文的,如果是我的自定義類,我通過鏈接到超級方法做驗證正常。如果它不是我的自定義子類,則返回YES以指示有效性。

當然,你可以讓這個更細緻,但你希望得到的想法:你試圖確定這是你的應用程序的標準保存或iCloud導入保存,並相應地分支。