議論をまとめるには:
- 2 つの管理対象オブジェクト エンティティ A と B
- A と B は 1 対 1 の逆の関係にあります
- 関係の両方向には無効化削除ルールがあります
問題: しばらくして、エンティティ A のインスタンスをマーシャリングし、その関係を newB に変更しようとしました (しばらく前に oldB との関係があった後) (たとえば、AB = newB)、コア データの例外が発生します。 :
CoreData は、「0x1e1515a0 x-coredata://90361082-A433-41A0-9F4E-BA3F032B193D/oldB/p7」の障害を解決できませんでした
調査とテストの結果、参照された oldB エンティティが削除され、コア データで使用できなくなったため、このエラーが発生しました。(私は信じています)Core DataがoldBにアクセスしてAとの関係を無効にしようとしているため、例外がスローされていますが、oldBがなくなっているため明らかにできません。
私が理解していないのは、どのように/なぜこの状態になったのかです。なぜなら、(コードの実行の前のある時点で) removeObject: oldB を実行したとき、Core Data は関係を無効にする必要があったため、上記を実行しているときに、 AB == nil を期待しています。
ほとんどの場合、これは適切に機能しているように見えます。ただし、これが発生すると、データベースが削除/復元されるまで、アプリは完全に使用できなくなります。
だから、私はいくつかの質問に答えてもらいたいと思っています:
- なぜこれが起こっているのでしょうか?これは、本番環境では必ずしも発生しない開発作業 (たとえば、removeObject:oldB が完了する前にプロセスを強制終了するなど) の影響である可能性はありますか?
- 私の回復オプションは何ですか? @try および @catch 例外ハンドラーを使用できると思いますが、 @catch ハンドラーで同じ問題が発生するため、コアデータのトリックがない限り、それが最終的に違いを生むかどうかはわかりません。関係を「強制終了」することを認識していません(技術的にデータグラフを壊すため、存在しないと思います)。
- 私のデータ グラフの場合、A と B の関係は「緩い」ものであり、実際には問題になりません (実際、B オブジェクトはジョブの完了後に削除されます)。A から独立した B のクリーンアップ プロセスを実施しているため、これらのまれなインスタンスで Core Data が詰まらないように、「アクションなし」の削除ポリシーを使用する方がよいでしょうか?
事前に知っているかもしれない洞察に感謝します!
アップデート:
私はいくつかの @try および @catch ブロックをいじっています。これが私が見つけたものです:
@try {
if (A.B.A) // Relationship check. Will throw exception if B is missing
nil;
}
@catch {
[moc deleteObject:A.B];
[moc save:nil];
}
上記の場合、@catch コードが実行されますが、保存時に Core Data は注釈をスローします。
注釈: オブジェクト A の対一関係 B の失われた削除伝達を修復しています
次に、コードを続行しようとしましたが、AB を再度変更しようとすると、フォルト例外で開始した場所に戻ります。
そこで、@catch ブロックを次のように変更してみました。
@catch {
[moc deleteObject:A.B];
A.B = nil;
[moc save:nil];
}
興味深いことに、deleteObject と設定 AB = nil は機能しましたが、保存時に元の例外がスローされます。
CoreData は、「0x2009b1e0 x-coredata://90361082-A433-41A0-9F4E-BA3F032B193D/B/p10」の障害を解決できませんでした
つまり、この状況でできることはほとんどないように見えます。なぜなら、Core Data はオブジェクト グラフをすべての犠牲を払って (アプリを実行する機能を含めて) 維持することによってその仕事をしているからです!
データストア全体を再起動する以外に、何か提案はありますか?