1

議論をまとめるには:

  • 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 はオブジェクト グラフをすべての犠牲を払って (アプリを実行する機能を含めて) 維持することによってその仕事をしているからです!

データストア全体を再起動する以外に、何か提案はありますか?

4

1 に答える 1

2

catch ブロックで A と B の両方を削除することで、問題を回避できました。

@try {
 if (A.B.A) // Relationship check. Will throw exception if B is missing
  nil;
 }
@catch {
 [moc deleteObject:A.B];
 [moc deleteObject:A];
 [moc save:nil];
 }

ただし、A が重要である (B は重要ではない) ため、これは理想的ではありません。幸いなことに、オブジェクト グラフ全体を失うコストよりもはるかに低いコストで A を再生成できます。本番コードを機能させるために、このソリューションは適切だと思いますが、理想的ではありません。

それでもエンティティAの保存を可能にする答えが欲しいです...

于 2013-02-26T14:31:29.447 に答える