web-dev-qa-db-ja.com

NSRunLoopを理解する

誰がNSRunLoopとは何か説明できますか?私が知っているようにNSRunLoopNSThreadに関連するものですか?だから私は次のようなスレッドを作成すると仮定します

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

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

だから、このスレッドが彼の仕事を終えた後、右? RunLoopsを使用する理由、または使用する場所from Apple docs何か読んだことがありますが、明確ではないので、できるだけ簡単に説明してください

97
taffarel

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

各NSThreadには独自の実行ループがあり、currentRunLoopメソッドを介してアクセスできます。

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

特定のスレッドの実行ループは、1つ以上の入力ソースにデータまたはイベントが含まれるまで待機し、適切な入力ハンドラーを起動して、「準備ができた」各入力ソースを処理します。

その後、ループに戻り、さまざまなソースからの入力を処理し、実行する作業がない場合は「スリープ」します。

これは非常に高度な説明です(あまりにも多くの詳細を避けようとしています)。

編集

コメントに対処する試み。私はそれをバラバラにしました。

  • それは、スレッド内でループを実行するためにのみアクセス/実行できることを意味しますか?

確かに。 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

189
Jody Hagins

RunLoopsは、何かが起こる箱のようなものです

基本的に、RunLoopでは、いくつかのイベントを処理してから戻ります。または、タイムアウトに達する前にイベントを処理しない場合に戻ります。非同期NSURLConnectionsに似ていると言えます。現在のループを妨げることなくバックグラウンドでデータを処理しますが、同時にデータを同期的に必要とします。これは、非同期NSURLConnectionを作成し、呼び出し時にデータを提供するRunLoopを使用して実行できます。次のようなRunLoopを使用できます。

NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];

while (YourBoolFlag && [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]) {
    loopUntil = [NSDate dateWithTimeIntervalSinceNow:0.1];
}

このRunLoopでは、他の作業を完了してYourBoolFlagfalseに設定するまで実行されます。

同様に、スレッドで使用できます。

これがお役に立てば幸いです。

8

実行ループとはseparatesinteractiveapps fromcommand-lineツール。

  • コマンドラインツールは、パラメーターを指定して起動し、コマンドを実行して終了します。
  • 対話型アプリwaitユーザーの入力、反応、待機の再開。

ここ から

ユーザーがタップしてそれに応じて応答するまで待機し、completionHandlerを取得してその結果を適用するまで待機し、タイマーを取得して機能を実行するまで待機できます。ランループがない場合は、ユーザーのタップをリッスン/待機することはできません。ネットワークコールが発生するまで待つことはできません。x分で目覚めることはできません。

また、 このコメント から:

バックグラウンドスレッドには独自のランループがありませんが、1つだけ追加できます。例えば。 AFNetworking 2.x やった。バックグラウンドスレッドでNSURLConnectionまたはNSTimerの真の手法として試されましたが、新しいAPIを使用する必要がなくなるため、これ以上は行いません。しかし、URLSessionは、たとえば ここでは単純なリクエストです 、メインキューで[画像の左パネルを参照]完了ハンドラーを実行しており、バックグラウンドスレッドで実行ループがあることがわかります。

2
Honey

実行ループは、スレッドに関連する基本的なインフラストラクチャの一部です。実行ループは、作業をスケジュールし、着信イベントの受信を調整するために使用するイベント処理ループです。実行ループの目的は、実行する作業がある場合はスレッドをビジー状態に保ち、スレッドがない場合はスレッドをスリープ状態にすることです。

ここから


CFRunLoopの最も重要な機能は、CFRunLoopModesです。 CFRunLoopは、「Run Loop Sources」のシステムで動作します。ソースは1つまたは複数のモードの実行ループに登録され、実行ループ自体は特定のモードで実行されます。イベントがソースに到着すると、ソースモードが実行ループの現在のモードと一致する場合にのみ、実行ループによって処理されます。

ここから

0
dengApro