5

私のアプリには、View Controllerが依存して渡すコンテキストNSPrivateQueueConcurrencyTypeの親として機能する「マスター」コンテキストがあります。NSMainQueueConcurrencyType非同期保存を利用するためにこれを行いたかったのです (このアプリは iCloud と Core Data を使用し、保存はユビキタス ログをエクスポートする多くの作業を行います)。セットアップは、この記事の最後に記載されている Zarra のアプローチに似ています。

アプリ内の保存は通常次のようになります。

[context save:nil];
[context.parentContext performBlock:^{
     [context.parentContext save:nil];
}];

これは小さな編集/更新にはうまくいくようですが、多くのオブジェクトを削除するとどうなるかわかりません (たとえば、何百ものタスク オブジェクトが関連するプロジェクトを削除するなど)。

その状況では、保存は非同期ですが、メイン スレッドがセマフォ待機状態になり (デバッガーを一時停止したときに見られるように)、バックグラウンドのプライベート コンテキストが終了するまで効果的にブロックされているように見えます (UI でスクロールできません)。保存。

実際、この非同期保存パターンにもかかわらず、1 つのオブジェクトをスワイプして削除すると、顕著な遅延が発生することに気付きました。そのため、アプリ内のすべての削除が遅いようです。

あるいは、新しいNSPrivateQueueConcurrencyTypeコンテキストを割り当て、その永続ストア コーディネーターを AppDelegate のメイン PSC に設定し、削除と保存を実行すると、多くの作業が行われますが、UI がブロックされることはありません (ただし、心配する必要があります)コンテキストの調整、メイン コンテキストでの再取得について)。

私が間違っていた可能性のあるアイデアはありますか、またはこの動作も見ましたか?

4

1 に答える 1

8

削除には時間がかかる場合があります。彼らはすべての関係を修正する必要があります。大規模な削除を行う場合は、いくつかの作業を行う必要があります。

まず、削除がバックグラウンドで行われているときに UI がブロックされるのはなぜですか? そのバックグラウンド スレッドは削除ブロックの実行で非常にビジーであり、削除が行われている間、UI はデータを更新するためにフェッチしようとしているためです。

実際の作業を実行するスレッドは FIFO キューによって管理されるため、大きなタスクを実行するように指定すると、実行時間の長いタスクが完了するまで他のタスクを実行できなくなります。

おそらくFRCを使用しており、オブジェクトと関係が変更されたときに更新を取得しようとしています。

大規模な削除がある場合は、フェッチを変更して、削除が行われている間はデータの現在の MOC のみを参照するようにすることができます。削除が完了したら、フェッチ要求に、ストア自体へのクエリに戻るように指示できます。

また、大量のものを削除する場合は、別のスレッドで自動解放プール内の小さなチャンクで実行することをお勧めします。そのバックグラウンド スレッドから、一度に小さなチャンクを削除し、performBlockAndWait. こうすることで、削除要求でワーカー スレッドのキューをロードせず、UI スレッドでその要求を処理できます。より速く。

または、GCD の高度な機能を使用して、作業をワーカー スレッドにフィードするために使用される優先度の高いキューと優先度の低いキューを設定することもできます。書き込みを優先度の低いキューに入れ、読み取りを優先度の高いキューに入れることができます。

于 2012-08-03T20:46:21.953 に答える