アプリで解決しようとしている問題に関して、一般的な客観的パターン/練習問題があります。ここでは、同様の目的 c に焦点を当てた質問/回答をまだ見つけることができませんでした。
私のアプリは、私が「レコード」と呼ぶオブジェクトの可変配列を保持しています。アプリはレコードを収集し、次の 2 つの方法のいずれかでその配列に配置します。
- アプリのサンド ボックス内でローカルに利用可能な SQLite データベースからデータを読み取ります。通常、読み取りは非常に高速です。
- Web サービスから非同期的にデータを要求し、それが完了するのを待ってから、データを解析します。読み取りは高速ですが、多くの場合そうではありません。
アプリがデータベースからの読み取り (1) と Web サービスからのデータの要求 (2) を実質的に同時に行う場合があります。(2) が終了する前に (1) が終了し、変更可能な配列にレコードを追加しても競合が発生しないことがよくあります。
ある時点で、SQLite 読み取りプロセスに予想よりも少し時間がかかり、非同期要求が終了して同じことを行うのとまったく同じ時刻にオブジェクトを可変配列に追加しようとするのではないかと心配しています。またはその逆。これらは、テストが難しいと思われるエッジ ケースですが、確実にアプリがクラッシュするか、少なくともレコードの配列に問題が発生する可能性があります。
また、レコードが変更可能な配列にマージされることも指摘しておく必要があります。例: (1) が最初に実行されて 10 レコードが返された場合、(2) が終了して 5 レコードが返された直後に、可変配列には 15 レコードすべてが含まれます。データを上書きするのではなく、結合しています。
私が知りたいのは:
- (1) または (2) のプロセスが終了したときに、同じ可変配列インスタンスにオブジェクトを追加しても安全ですか?
- Objective-C でこの種の処理を実装するための適切なパターン/プラクティスはありますか?
- これには可変配列へのアクセスのロックが含まれるので、(1) オブジェクトをそれに追加しているとき (2) (1) が完了するまでオブジェクトを追加できませんか?
共有できる情報に感謝します。
[編集#1]
後世のために、この URL は NSOperations と NSOperationQueue の使用方法を理解するのに非常に役立つことがわかりました。少し古くなっていますが、それでも動作します:
http://www.raywenderlich.com/19788/how-to-use-nsoperations-and-nsoperationqueues
また、私が解決しようとしている問題について具体的に述べているわけではありませんが、使用する例は実用的で理解しやすいものです。
[編集#2]
私は、ローカルで読み取り、必要に応じて、ローカル読み取りが終了した後に Web サービスをヒットする、danh によって提案されたアプローチを採用することにしました (とにかく高速である必要があります)。Taht 氏によると、同期の問題を完全に回避しようとしています。なんで?Appleがそう言っているので、ここに:
同期を完全に回避する
取り組んでいる新しいプロジェクトの場合、また既存のプロジェクトの場合でも、コードとデータ構造を設計して同期の必要性を回避することが最善の解決策です。ロックやその他の同期ツールは便利ですが、アプリケーションのパフォーマンスに影響を与えます。また、全体的な設計によって特定のリソース間で高い競合が発生した場合、スレッドはさらに長く待機する可能性があります。
並行性を実装する最善の方法は、並行タスク間の相互作用と相互依存性を減らすことです。各タスクが独自のプライベート データ セットで動作する場合、ロックを使用してそのデータを保護する必要はありません。2 つのタスクが共通のデータ セットを共有している場合でも、そのセットを分割する方法や、各タスクに独自のコピーを提供する方法を検討できます。もちろん、データ セットのコピーにもコストがかかるため、決定を下す前に、それらのコストと同期のコストを比較検討する必要があります。