現在表示されているiPhone Tableviewのデータを更新する長時間実行操作のベストプラクティスは何ですか?
-
06-07-2019 - |
質問
背景:
オブジェクトのリストを表す独自のPlaceListクラスでそれぞれサポートされている約8つのセクションを表示するテーブルビューがあります(実装ではNSMutableArrayを使用します)。合計で約200個のオブジェクトがあります。各セクションは、オブジェクトが現在の場所からどれだけ離れているか(たとえば、1マイル以内、10、25、50など)に対応します。
ときどき、CoreLocationからの非同期通知に応答し、各オブジェクトが属するセクションを再計算し、各オブジェクト(各セルに表示される)の距離を更新し、各リストを再配置する必要があります。次に、テーブルビューをリロードします。 viewWillAppearでもこの操作を行います。
更新を実行する操作(PlaceListのメソッド)内で、OSによって複数のスレッドから呼び出された場合に@synchronized(self)を使用しました(自分で別のスレッドを使用していません)プレゼント)。ただし、現在この操作の結果、UIが時々「フリーズ」しているように感じられるため、独自のスレッドでそれを行う方法を検討しています。
質問:
-
Table Viewを支えるデータに対して、この種の長時間実行操作を行う最良の方法は何ですか?私が見る限り、バックグラウンドスレッドをスピンオフして操作を行うことは安全ではありません。実行時にperformSelectorを使用してメインスレッドのテーブルビューをリロードしても、ユーザーがセルをタップする可能性があります操作の実行中にデータが表示と一致していません。また、あらゆる種類のロックを追加すると、目的が損なわれます。
-
UIとCoreLocation locationManagerは同じスレッドで通知を送信しますか?つまり、PlaceListで@synchronized(self)を安全に省くことができますか?
解決
あなたの問題についての私の理解です。大量のデータのリストがあり、ある時点で無効になります。再び有効にするには、テーブルを再描画する前に処理を行う必要があります。
これが正しい場合、いくつかのオプションがあります。
1)データをダブルバッファリングします。 「だった」ものを表示している限り、正しい場合、ユーザーは問題なく操作できます。データを再処理するトリガーを取得したら、コピーを使用してバックグラウンドで作業し、完全に再描画する準備ができたら更新します。その更新は突然大きくなる場合がありますが、表示されるデータは常に正しいか、少なくとも正気であり、UIは機能し続け、ユーザーを怖がらせません。
これにより、通知がデータを変更せず、同時に表示しようとしないため、スレッドの問題が大幅に回避されます。
AFAIK、FacebookアプリケーションはTwitterFonと同様にこれを行うようです。少なくともそういう感じです。確かに言うのは難しい。
2)ロード画面!面白くありませんが、機能します。データが悪いことがわかったら、半透明のパネルを開いて、ユーザーに少しハングアップするように伝えます。
実際には、今、またはそれ以降のアップデートになります。アプリケーションでどのトレードオフが最も意味をなすかを決定する必要があります。