アプリケーション UI (メイン スレッド) への影響を最小限に抑えながら、かなり大きなコア データ ベースのデータセットをバックグラウンドで更新する最善の方法を探しています。
このトピックについては、次のような優れた資料があります。
- WWDC 2013 のセッション 211 (コア データ パフォーマンスの最適化とデバッグ、25:30 頃から)
- objc.io からの大きなデータ セットのインポート
- objc.io の一般的なバックグラウンド プラクティス(バックグラウンドでのコア データ)
- ネストされた管理対象オブジェクト コンテキストを使用した舞台裏
私の調査と個人的な経験に基づいて、データベース (SQLite) レベルでのみデータを共有する 2 つの別個のコア データ スタックを効果的に使用することが、利用可能な最良のオプションです。これはNSPersistentStoreCoordinators
、それぞれが独自の を持つ2 つの別個の が必要であることを意味しNSManagedObjectContext
ます。データベースで先行書き込みロギングを有効にすると (iOS 7 以降のデフォルト)、ほぼすべてのケースでロックの必要性を回避できます (ただし、2 つ以上の同時書き込みがある場合を除きますが、これは私のシナリオではありそうにありません)。
効率的なバックグラウンド更新を行い、メモリを節約するには、データをバッチで処理し、バックグラウンド コンテキストを定期的に保存する必要もあります。これにより、ダーティ オブジェクトがデータベースに保存され、メモリからフラッシュされます。この時点で生成されるを使用しNSManagedObjectContextDidSaveNotification
て、背景の変更をメイン コンテキストにマージできますが、通常、バッチが保存された直後に UI を更新することは望ましくありません。バックグラウンド ジョブが完全に完了するまで待ってから、UI を更新します (WWDC セッションと objc.io の両方の記事で推奨されています)。これは事実上、アプリケーションのメイン コンテキストが一定期間データベースと同期していないことを意味します。
つまり、変更をマージするようにメイン コンテキストにすぐに指示せずに、この方法でデータベースを変更した場合、何が問題になる可能性があるのでしょうか? 私はそれがバラのすべての太陽の光ではないと仮定しています.
頭の中にある特定のシナリオの 1 つは、メイン コンテキストにロードされたオブジェクトに対して障害を解決する必要がある場合、バックグラウンド操作によってそのオブジェクトがデータベースから削除された場合にどうなるかということです。これは、たとえば、batchSize を使用してオブジェクトを段階的にメモリにフェッチする NSFetchedResultsController ベースのテーブル ビューで発生する可能性がありますか? つまり、まだ完全にフェッチされていないオブジェクトは削除されますが、オブジェクトをロードする必要があるポイントまでスクロールします。これは潜在的な問題ですか?他のことがうまくいかないことはありますか?この件に関するご意見をいただければ幸いです。