web-dev-qa-db-ja.com

NSDefaultRunLoopMode vs NSRunLoopCommonModes

スタックオーバーフローの親愛なる人々、

前回と同じように、私はここで最近つまずいた質問を持ち出します。誰かが私に光を当ててくれることを願っています。

UIScrollViewMPMapViewなどの背後にある大きなファイルをダウンロードしようとすると、iPhoneの画面に触れるとすぐにダウンロードプロセスが停止します。ありがたいことに、 Jörn による素晴らしいブログ投稿では、接続にNSRunLoopCommonModesを使用する代替オプションが提案されています。

NSDefaultRunLoopModeとNSRunLoopCommonModesの2つのモードの詳細を調べますが、Appleドキュメントは、

NSDefaultRunLoopMode

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

NSRunLoopCommonModes

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

CFRunLoopAddCommonMode

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

誰でも人間の言語でこの2つを説明できますか?

101
Stkim1

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

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

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

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

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

いくつかメモを追加して閉じたいと思います。

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

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

187
viggio24