1. ホーム
  2. iphone

[解決済み] NSDefaultRunLoopModeとNSRunLoopCommonModesの比較

2022-08-18 03:40:51

質問

の後ろにある大きなファイルをダウンロードしようとすると、常に UIScrollView , MPMapView などと入力すると、iPhoneの画面をタッチしたとたんにダウンロードが止まってしまいます。ありがたいことに Jörn は、別の選択肢を提案しています。 NSRunLoopCommonModes を使用することを提案します。

NSDefaultRunLoopModeとNSRunLoopCommonModesという2つのモードについて詳しく調べてみましたが、appleのドキュメントでは親切に説明されておらず、以下のように書かれているのみでした。

NSDefaultRunLoopMode(デフォルトのループモード

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

NSRunLoopCommonModes

<ブロッククオート

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

CFRunLoopAddCommonMode

<ブロッククオート

ソース、タイマー、オブザーバーは1つまたは複数のランループモードに登録され、ランループがこれらのモードのいずれかで実行されているときのみ実行されます。共通モードは、ランループのモードのセットで、これらのモードで共有されるソース、タイマ、オブザーバのセットを定義することができます。例えばソースを特定のランループの各モードに登録するのではなく、ランループの共通擬似モードに一度登録すれば、共通モードセット内の各ランループモードに自動的に登録されます。同様に、共通モードセットにモードが追加されると、すでに共通擬似モードに登録されているソース、タイマ、オブザーバは、新たに追加された共通モードに追加される。

どなたか、この2つを人間の言葉で説明していただけませんか?

どのように解決するのですか?

実行ループは、システムが眠っているスレッドを起こして、非同期イベントを管理できるようにするメカニズムです。通常、スレッド (メイン スレッドを除く) を実行するとき、スレッドを実行ループで開始するかどうかのオプションがあります。スレッドが外部イベントとのインタラクションやタイマーを伴わないある種の長期的な処理を実行する場合は、ランループは必要ありませんが、スレッドが受信イベントに反応する必要がある場合は、新しいイベントが到着したときにスレッドを起動するためにランループに接続する必要があります。これは NSURLConnection 生成されたスレッドの場合、(ネットワークからの)着信イベントでのみ起動するからです。

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

通常、すべてのランループは、入力イベントを管理するためのデフォルトの方法を確立する "デフォルトモード" に設定されています。たとえば、マウス ドラッグ (Mac OS) またはタッチ (iOS) イベントが発生するとすぐに、この実行ループのモードはイベント トラッキングに設定されます。これは、新しいネットワーク イベントでスレッドが起動されず、ユーザー入力イベントが終了して実行ループが再びデフォルト モードに設定されると、これらのイベントが後で提供されることを意味します。

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

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

最後に、いくつかの注意点を付け加えて終わりたいと思います。

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

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