NSDefaultRunLoopMode と NSRunLoopCommonModes 質問する

NSDefaultRunLoopMode と NSRunLoopCommonModes 質問する

大きなファイルをダウンロードしようとするとUIScrollViewMPMapViewiPhoneの画面に触れるとすぐにダウンロードが停止してしまいます。ありがたいことに、ヨルンNSRunLoopCommonModes接続に使用する代替オプションを提案します。

それで、NSDefaultRunLoopModeとNSRunLoopCommonModesという2つのモードの詳細を調べることになりますが、Appleのドキュメントでは、

NSデフォルト実行ループモード

NSConnection オブジェクト以外の入力ソースを処理するモード。これは最も一般的に使用される実行ループ モードです。

NSRunLoop共通モード

この値をモードとして使用して実行ループに追加されたオブジェクトは、「共通」モードのセットのメンバーとして宣言されているすべての実行ループ モードによって監視されます。詳細については、CFRunLoopAddCommonMode の説明を参照してください。

CFRunLoopAddCommonMode

ソース、タイマー、およびオブザーバーは、1 つ以上の実行ループ モードに登録され、実行ループがそれらのモードのいずれかで実行されている場合にのみ実行されます。共通モードは、これらのモードで共有されるソース、タイマー、およびオブザーバーのセットを定義できる実行ループ モードのセットです。たとえば、ソースを特定の実行ループ モードに登録する代わりに、実行ループの共通疑似モードに 1 回登録すると、共通モード セット内の各実行ループ モードに自動的に登録されます。同様に、モードが共通モード セットに追加されると、共通疑似モードに既に登録されているソース、タイマー、またはオブザーバーは、新しく追加された共通モードに追加されます。

誰かこの2つを人間の言葉で説明してくれませんか?

ベストアンサー1

実行ループは、システムがスリープ状態のスレッドを起動して、非同期イベントを管理できるようにするメカニズムです。通常、スレッドを実行する場合 (メイン スレッドを除く)、スレッドを実行ループで開始するかどうかを選択できます。スレッドが外部イベントとのやり取りやタイマーなしで何らかの長時間実行される操作を実行する場合、実行ループは必要ありませんが、スレッドが着信イベントに応答する必要がある場合は、新しいイベントが到着したときにスレッドを起動できるように、実行ループに接続する必要があります。これは、NSURLConnection生成されたスレッドの場合で、着信イベント (ネットワークから) が発生したときにのみ起動します。

各スレッドは、複数の実行ループに関連付けることも、異なるモードで動作するように設定できる特定の実行ループに関連付けることもできます。「実行ループ モード」は、特定のイベントをいつ配信するか、または後で配信するためにそれらを収集するかについてのルールを確立するために OS が使用する規則です。

通常、すべての実行ループは、入力イベントを管理するデフォルトの方法を確立する「デフォルト モード」に設定されています。たとえば、マウス ドラッグ (Mac OS) またはタッチ (iOS) イベントが発生するとすぐに、この実行ループのモードはイベント トラッキングに設定されます。つまり、新しいネットワーク イベントではスレッドは起動されませんが、これらのイベントは、ユーザー入力イベントが終了し、実行ループが再びデフォルト モードに設定されたときに後で配信されます。これは明らかに、OS アーキテクトがバックグラウンド イベントではなくユーザー イベントを優先するために行った選択です。

スレッドの実行ループモードを変更する場合はNSURLConnection、を使用してscheduleInRunLoop:forModes:、スレッドを特別な実行ループに割り当てることができます。モード、特定のデフォルトの実行ループではなく。 と呼ばれる特別な疑似モードは、NSRunLoopCommonModesイベント追跡を含む多くの入力ソースによって使用されます。たとえば、NSURLConnectionのインスタンスを共通モードに割り当てることは、そのイベントを「デフォルト モード」に加えて「追跡モード」に関連付けることを意味します。 スレッドを に関連付けることの利点/欠点の 1 つは、NSRunLoopCommonModesスレッドがタッチ イベントによってブロックされないことです。

共通モードに新しいモードを追加できますが、これは非常に低レベルの操作です。

最後にいくつか注釈を加えたいと思います。

  • 通常、テーブル ビューでは、ネットワークからダウンロードした画像またはサムネイルのセットを使用する必要があります。テーブル ビューのスクロール中にネットワークからこれらの画像をダウンロードすると、ユーザー エクスペリエンスが向上する (スクロール中に画像を表示できるため) と考えるかもしれませんが、スクロールの滑らかさが大幅に低下する可能性があるため、これは有利ではありません。この例では、実行ループは使用しないでください。デリゲート メソッドを使用して、スクロールが終了したことを検出し、テーブルを更新してネットワークから新しいアイテムをダウンロードする方がNSURLConnection適切です。UIScrollView

  • 実行ループ管理の問題からコードを「保護」するのに役立つ GCD の使用を検討してください。上記の例では、ネットワーク要求をカスタム シリアル キューに追加することを検討してください。

おすすめ記事