1. ホーム
  2. ios

[解決済み] NSRunLoopを理解する

2022-09-17 15:07:36

質問

どなたか NSRunLoop というのは、私が知っているように NSRunLoop とは何か関係があるのでしょうか? NSThread に接続されているものですよね?そこで、次のようなThreadを作成したとします。

NSThread* th=[[NSThread alloc] initWithTarget:self selector:@selector(someMethod) object:nil];
[th start];

-(void) someMethod
{
    NSLog(@"operation");
}

で、このスレッドが作業を終了した後、なぜ RunLoops を使用するのでしょうか? Appleのドキュメントから何かを読みましたが、私には明確ではありません。

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

実行ループは、(とりわけ)システムの入力ソース(ソケット、ポート、ファイル、キーボード、マウス、タイマーなど)を処理するメカニズムを提供する抽象化されたものです。

各NSThreadはそれ自身のランループを持ち、currentRunLoopメソッドを通してアクセスすることができる。

一般に、ランループに直接アクセスする必要はありませんが、I/O処理に使用するランループを指定できる(ネットワーキング)コンポーネントもあります。

与えられたスレッドの実行ループは、その入力ソースの 1 つまたは複数が何らかのデータまたはイベントを持つまで待機し、適切な入力ハンドラーを起動して、quot;ready." となった各入力ソースを処理します。

そうした後、ループに戻り、さまざまなソースからの入力を処理し、行うべき仕事がなければ "sleep"します。

これがかなりハイレベルな説明です (あまり詳細を書かないようにしています)。

EDIT

コメントへの対応の試み。 バラバラにしました。

  • ということは、スレッド内の実行ループにしかアクセス/実行できないってことですよね? ということですよね?

確かに。 NSRunLoopはスレッドセーフではないので、ループを実行しているスレッドのコンテキストからしかアクセスしてはいけません。

  • 実行ループにイベントを追加する簡単な例はありますか?

ポートを監視したい場合、そのポートをランループに追加するだけで、ランループはそのポートの活動を監視することになります。

- (void)addPort:(NSPort *)aPort forMode:(NSString *)mode

また、タイマーを明示的に追加する場合は

- (void)addTimer:(NSTimer *)aTimer forMode:(NSString *)mode

  • ループに戻るとはどういうことですか?

実行ループは、(そのモードに従って)各反復ごとにすべての準備されたイベントを処理します。 一般的な答えの範囲を少し超えているので、実行モードについて発見するために、ドキュメントを見る必要があります。

  • スレッドを開始するとき、実行ループは非アクティブですか。

ほとんどのアプリケーションでは、メインのランループは自動的に実行されます。 しかし、実行ループを開始し、スピンしたスレッドに着信するイベントに応答する責任はあなたにあります。

  • スレッドの外側のスレッド実行ループにいくつかのイベントを追加することは可能ですか?

何を言っているのかよくわかりません。 実行ループにイベントを追加するのではありません。 入力ソースとタイマーソースを追加します(ランループを所有するスレッドから)。 そして、ランループはそれらのアクティビティを監視します。 もちろん、他のスレッドやプロセスからデータ入力を提供することはできますが、入力は、ランループを実行しているスレッドでそれらのソースを監視しているランループによって処理されます。

  • ランループを使用してスレッドを一時的にブロックすることができるということでしょうか。

確かに。 実際、実行ループは、イベントハンドラが戻るまでイベントハンドラに留まります。 これは、どんなアプリでも簡単に見ることができます。 スリープするIOアクション(例えば、ボタン押下)用のハンドラをインストールします。 そのメソッドが完了するまで、メインの実行ループ (および UI 全体) をブロックすることになります。

同じことが任意の実行ループに適用されます。

ランループについては、以下のドキュメントを読むことをお勧めします。

https://developer.apple.com/documentation/foundation/nsrunloop

と、それらがスレッド内でどのように使用されるかを説明します。

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1