2016-04-15 13 views
4

新しいモデルのバージョンで、既存のアプリケーションに固有の制約を導入します。コアデータ固有の制約 - 保存時に「無効なオブジェクトへの参照のダングリング」

モデルには、エンティティPetとオプションの一対一の関係を持つentity Personがあります。 Personの削除ルールはカスケードであり、Petの逆関係削除ルールは無効です。 Personには1対1の関係もある別のエンティティ、Jobがあります。しかし、削除ルールと逆削除ルールはどちらも無効です。

Personには、私が独自に作成した「personID」プロパティがあります。

メインキューコンテキストでは、IDがxxxのPersonインスタンスがあり、Petが設定されていません。その人を「Charlie」と呼ぶことにしましょう。私もJobを作成し、それを "iOS Dev"として設定し、それをCharlieの仕事のプロパティに割り当てます。

子のプライベートキューコンテキストでは、ID xxx(ユニーク制約)の新しい「Charlie」を挿入し、Petを作成して設定します。私は仕事を設定しません。私は問題なしで子のコンテキストを保存します。

直後、メインキューコンテキストを保存しようとしました。しかし、その直前に、メインキューコンテキストのinsertedObjectsプロパティを調べて、期待どおりID xxxのPersonのインスタンスを確認します。私が期待しているのは、この2番目のインスタンスが一意の制約によって処理され、前の段落の元のPersonインスタンスとマージされるということです。しかし、私は実際にMOCのsaveを呼び出すとき、:メソッドを、それが例外をスローし、私はNSErrorオブジェクトを調べる:

エラードメイン= NSCocoaErrorDomainコード= 1550「操作が を完了できませんでした(ココアエラー1550。 ) "UserInfo = { 無効なオブジェクトへの参照のダングル= null

例外を回避する方法はありますか?私はコアデータの中の「ダングリングリファレンス」に慣れていますが、関係が誤って設定されていることを意味しますが、何度もそれを繰り返してきていますので、それ以外は何をトラブルシューティングするか分かりません。 NSMergeByPropertyObjectTrumpMergePolicyマージポリシーを使用して、すべてのコンテキストを関連付ける必要があります。

明らかにこれは従うことが少し難しいですので、私はケースの誰にGithubの上でサンプルプロジェクトを投げたことは興味を持っている:https://github.com/bpapa/core-data-unique-bug

答えて

4

これでコードレベルのサポートチケットが作成され、アップルのエンジニアがバグがあることを確認しました。この問題を回避するには、スーパーを呼び出す独自のマージポリシーを作成し、手動で関係が両端で設定されていることを確認することをお勧めします。

+0

私の場合、Xcode 8.2にアップグレードすると問題が消えました! – bruce1337

+0

これは良いことです。私のアプリケーションでは、私自身のマージポリシーを書いてもそれを修正していないことがわかったので、実際にはユニークな機能に頼るのをやめてしまった。つまり、たくさんの余分な作成または更新のコードがあり、コアデータに保存する私の操作。うまくいけば、私はこれを再訪することができます。 – bpapa

+0

10月29日に私の喜ばしいコメントを撤回する必要があります。この問題は復讐して戻ってきました。私は今、シミュレータの内容をリセットしたので、1550の参照エラーが消えてしまったように見えます。私の場合、コンテンツがサーバーからリフレッシュされ、アプリケーションがCore Dataの既存のオブジェクトを更新しようとすると、1550になります。 私は今リリースバージョン8.2を使用していますが、まだXcodeのバグが原因ではないと仮定して、問題を解決しようとしています。 – bruce1337

1

新しいiOSの9ユニーク制約戦略を採用する場合、あなたは確認する必要があります両方のコンテキストに同じマージポリシーが設定されていることを確認してください。

注これは、あなたがオブジェクトの新しいインスタンスがnilであり、あなたの意図が常にオブジェクトを「強化」することである属性/関係を持つシナリオを持っている場合は、ないヘルプご意志すなわち欠落している属性を埋めること既存のものを更新する。

それ以外の場合、pre-iOS9の場合、以下が有効です。

おそらく、採用しているマージポリシーの意味について誤解があります(NSMergeByPropertyObjectTrumpMergePolicy)。これは、メモリ内にオブジェクトの1つのバージョンがあり、永続ストア内にオブジェクトの1つのバージョンがあり、別のコンテキストのメモリ内に2つのバージョンがないという状況を指します。ヘッダファイルから:

このシングルトンポリシーは、永続ストアのオブジェクトバージョンと現在のメモリバージョンとの競合をマージします。

したがって、新しいオブジェクトを作成するあなたのプロセスが正しいアプローチではありません。

代わりに、固有のIDを使用して子コンテキストにPersonを取得する必要があります。

また、objectID(不透明なCore Dataアーティファクト)を子コンテキストで使用できるようにして、オブジェクトグラフ内の同じオブジェクトへの参照をobjectWithID:で取得することもできます。

+0

しかし、私はiOS 9のユニーク制約の全目的は、「フェッチまたは作成する」タイプのものではないということですか?私は、Unique Constraintsが解決しようとしている問題の1つと考えられる、別のスレッドで作成されるレコードの重複を避けるためにこれをやっています。 – bpapa

+0

OK - どこから来ているのか分かります。 *両方のコンテキスト*に対してマージポリシーを設定する必要があります。そうしないと、動作しません。私はまだ、より明示的でデバッグ可能なので、むしろ不透明なマージ戦略に頼るのではなく、同じ管理対象オブジェクトで作業する方が好きですが、あなたのアプローチもうまくいくはずです。 – Mundi

+0

それはすべきです!私はここに含まれるすべてのコンテキストでマージポリシーを設定しています。私はこれがAppleのバグだと確信していますが、調査中です。 – bpapa

0

バックグラウンドコンテキストからの保存通知を使用して変更をメインコンテキストにマージします。 Apples Earthquakesのサンプルを参照してください。

関連する問題