8

Objective-C ブロックは常に別のスレッドで実行されますか?

具体的には、NSURLConnection クラスの sendAsynchronousRequest:queue:completionHandler メソッドについてお尋ねします。これはシナリオです:

メイン スレッド (1 番目のスレッド) が sendAsynchronousRequest メソッドを呼び出し、sendAsynchronousRequest が 2 番目のスレッドで実行され、メソッドが完了すると NSOperationQueue によって管理され、commpletionHandler が呼び出されます。どのスレッドで実行されますか? 2スレッド?さらに別の3番目のスレッド?または1番目のスレッド?

ありがとう!

4

4 に答える 4

7

queue引数として指定した操作キューで実行します。

URL 要求のデータをロードし、要求が完了または失敗したときに操作キューでハンドラー ブロックを実行します。

queueパラメータは次のように文書化されています。

要求が完了または失敗したときにハンドラー ブロックがディスパッチされる操作キュー。

したがって、NSOperationQueue使用されるスレッドの正確な数に依存します。私はプーリング動作を期待しています - そのため、複数のスレッドが存在する可能性がありますが、必ずしもハンドラーごとに異なるスレッドを期待するわけではありません。

于 2012-10-02T06:06:49.417 に答える
7

ブロックは、Python や関数型言語のように単なるクロージャです。それらは「スレッドで実行」されず、呼び出された場所で実行されます。

int main(void)
{
    void (^f)(void) { printf("hello world!\n"); }
    f();
    return 0;
}

ディスパッチ キューもスレッドも何もなく、あなたが思っていることを実行します。

ただし、すべての優れたキャプチャ セマンティクスを備えたブロックを取得すると、どこでも実行をスケジュールする API が非常に魅力的になります。しかし、基本的には、ブロックは関数ポインターと同じであり、キャプチャされたすべての変数を含むアドホックな構造体であり、引数としてコールバックに渡されます (コンパイラでの実装方法でもあります)。

于 2012-10-25T21:53:19.730 に答える
4

ブロックは、指示された場所で実行されます。ブロック内のコードをラップしても、実行されるスレッドやキューには影響しません。特定のケースでは、文書化されているように、完了ブロックはqueueパラメーターで渡されたキューで実行されます。

キューとスレッドを本当に区別する必要があるかどうかはわかりませんが、重要な原則は、URLリクエストが呼び出し元のコードとは非同期に実行され、渡されたキューに対して完了ブロックが実行されることです。メソッドパラメータとして。

于 2012-10-02T06:07:59.110 に答える
4

他の人が言っているように、それはあなたが指定したどんなキューでも実行されます。これがバックグラウンドキューであり、メインスレッドでコードを実行する場合は、メインキューにアクセスするGCDブロックを除外できます。完了ブロックは次のようになります。

^(NSURLResponse *response, NSData *data, NSError*error){

   // do whatever in the background

   dispatch_async(dispatch_get_main_queue(), ^{
   // this block will run on the main thread
   });
}
于 2012-10-02T06:10:31.757 に答える