2015-11-04 10 views
9

コアデータのバッチ削除に関して多くの質問がありましたが、問題は解決していないようです。コアデータNSBatchDeleteRequestがオブジェクトをコンテキスト内に残しているように見える

コアデータを使用してiOS 9/Swiftアプリケーションを作成しています。今年のWWDCでは、Core Dataセッションに出席し、NSBatchDeleteRequestを使用して永続ストアから直接多数のオブジェクトを削除することができたことがわかりました。これは私のためにいくつかのオブジェクトでは動作しますが、他のものでは動作しません。私はそれが私の関係と関係があると思います。

私はSubjectCourseというオブジェクトグラフを持っています。そこには1対多の関係があります。科目は希望する数のコースを所有することができます。

私はsubjectが削除されたときsubjectに関連付けられているすべてのコースを削除することにしたいようCascadeの削除規則を持つSubjectの「コース」の関係が、あります。

逆は、Courseで「件名」、削除ルールはNullifyです。ここで、私はNullifyのAppleの説明に、ビット混乱しています:

オブジェクト間の関係を削除するが、いずれかのオブジェクトを削除しないでください。 これは、従業員の部署関係がオプションである場合、または次の保存操作の前に従業員ごとに新しい部署を設定した場合にのみ意味を持ちます。

これはかなり明確ですが、なぜ関係は削除されるのでしょうか、どちらのオブジェクトも削除されませんか?私はCourseを削除した場合、私はCourseを削除すると、削除Courseに障害がSubjectcoursesセットにNSSetに表示されないようにcoursesubjectから関係が削除されるようにしたいと思います。

エンティティ内のすべてのオブジェクトを削除する方法を提供したいと考えています。個別に取り出して削除しようとすると、coursecoursesが正しく削除され、Subjectののcoursesから削除されます。

coursesがいくつあるかわからず、すべての状況で高性能を確保したいので、すべてを削除するにはバッチ削除を使用すると考えましたcourses。問題は、Subjectsすべてを削除するのにNSBatchDeleteRequestを利用している間に、coursesの道に沿って(Cascadeのルールのために)すべてを削除しようとすると、すべてのオブジェクトをそのまま残しているように見えます。

私はすべてのCoursesを削除するNSBatchDeleteRequestを使用し、私は何SubjectsCoursesがまだ存在して見ることがMOCを照会すると、その後、両方のCoursesはまだ返されており、それらを所有するSubjectはまだそれらへの参照を持っています。これとは対照的に

、私はフェッチと個別Courseを削除し、私のその後の適切すべてCoursesSubjectの「コース」の関係が適切に変更されているように見えるため、空の配列を表示フェッチ。

はい、リクエストを実行した後にコンテキストを保存しています。コンテキストが店舗の機能について通知されない場合がありますが、すべてを再度削除すると、subjectsはうまく機能しました。ここで何が起こっているのですか?

+0

バッチ削除では削除ルールが無視されます。 https://stackoverflow.com/questions/32915874/can-i-use-nsbatchdeleterequest-on-entities-with-relationships-that-have-delete-r/46073965#46073965 – LShi

答えて

24

the WWDC 2015 session which describes NSBatchDeleteRequest「変更はコンテキストに反映されていません」と説明されています。あなたが見ているものは正常です。バッチ更新は、マネージオブジェクトコンテキストを経由するのではなく、永続ストアファイル上で直接動作するため、コンテキストはそれらを認識しません。フェッチして削除することでオブジェクトを削除すると、コンテキストを操作しているので、実際に行っている変更を知ることができます(実際には変更が実行されています)。

あなたがNSBatchDeleteResultTypeObjectIDsを使用する場合は、バッチの結果は、あなたのコンテキストを更新するmergeChangesFromRemoteContextSave:intoContexts:を使用して、コンテキストに戻って削除マージすることができます。コンテキストから他の管理オブジェクトがロードされていない場合は、おそらくresetを使用することもできます。

+0

ありがとうございます!私はリセットを使用し、それは働いた。あなたの答えを見る前に、私はコースがSQLiteデータベースから欠落していたことを知り、アプリケーションは再起動時にこれを反映していました。 –

+0

安全のためにmergeChangesメソッドに切り替えたいと思います。私は 'NSBatchDeleteResultTypeObjectID'として戻るように設定したバッチ削除結果のコピーを持っています。 'mergeChangesFromRemoteContextSave'の' changeNotificationData:[NSObject:AnyObject] 'に何を渡しますか? –

+0

'NSBatchDeleteResultTypeObjectID'を使用する代わりに、' NSManagedObjectContextDidSaveNotification'のために登録し、ブロックから 'mergeChangesFromRemoteContextSave'を呼び出しました。 –

2

私はバッチ削除後のコンテキストの世話をするために以下を追加しました。

[self.managedObjectContext refreshAllObjects]; 
関連する問題