次の単純なエンティティ モデルを考えてみましょう。エンティティ A には、bというエンティティ B との 1 対 1 の関係があります。エンティティ B には、 aと呼ばれる逆対一の関係があります。どちらの関係もオプションではありません。
A B
b < ----- > a
完全に同期を開始する 2 つのデバイス (1) と (2) があるとします。それぞれに、クラス A のオブジェクトが 1 つと、クラス B のオブジェクトが 1 つあり、それらは互いに関連付けられています。デバイス 1 にはオブジェクト A1 と B1 があり、デバイス B には同じ論理オブジェクト A1 と B1 があります。
次に、各デバイスでシミュレートされた変更が行われたとします。
デバイス 1 で、B1 を削除し、B2 を挿入して、A1 を B2 に関連付けます。次に、変更を保存します。
デバイス 2 では、B1 を削除し、B3 を挿入して、A1 を B3 に関連付けます。次に、変更を保存します。
デバイス 1 は、デバイス 2 からトランザクション ログをインポートしようとします。B3 が挿入され、A1 が B3 に関連付けられます。ここまでは順調ですが、B2 にはnilに等しい関係aが残されています。関係はオプションではないため、検証エラーが発生します。
B オブジェクトが 2 つあり、関連付けられる A オブジェクトが 1 つだけであるため、デバイス 2 でも同様のことが起こります。したがって、B オブジェクトの 1 つがnilに設定された関係を持つ必要があるため、常に検証エラーが発生する必要があります。
さらに悪いことに、将来の変更では、常に誤った B オブジェクトがぶら下がったままになり、検証に失敗します。実際には、ユーザーは関係をリセットしても問題を自分で解決することはできません。永久に壊れています。
問題は、このような検証エラーにどのように対処できるかということです。これはすべて、NSPersistentStoreDidImportUbiquitousContentChangesNotification
通知がトリガーされる前に発生します。アプリの mainNSManagedObjectContext
での検証エラーではなく、トランザクション ログを永続ストアに最初にインポートするときに発生する検証エラーです。
私が考えることができる唯一のオプションは、おそらくカスタムセッター ( setA:
) または B クラス自体の KVC 検証メソッド ( validateA:error:
) で無効な B オブジェクトを削除しようとすることです。これらはトランザクションログのインポート中にトリガーされるように見えるためです。 . しかし、これらのような副作用が許されているかどうかはわかりません。試してみると、その影響に関する厄介なログ メッセージが表示されるようです。
これを処理する正しい方法を知っている人はいますか?