121

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

これにより、NSDefaultRunLoopMode と NSRunLoopCommonModes の 2 つのモードの詳細を調べることができますが、アップルのドキュメントでは、

NSDefaultRunLoopMode

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

NSRunLoopCommonModes

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

CFRunLoopAddCommonMode

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

この2つを人間の言葉で説明できる人はいますか?

4

1 に答える 1

213

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

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

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

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

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

いくつかのメモを追加して締めくくりたいと思います。

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

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

于 2011-08-28T20:38:09.810 に答える