1

私が直面している状況について、小さな質問があります。私には2つの方法があります:

- (void)firstSelector {
    [self launchAsyncTask];
    ... do some work for a long time (10secs) ...
}

- (void)asyncTaskFinished {
    ... some work after 5secs of async task ...
}

firstSelectorを実行します。launchAsyncTaskこれは、と呼ばれるコールバックを持つ単なるバックグラウンドタスクですasyncTaskFinishedfirstSelector非同期タスクの起動後一定時間(たとえば10秒)実行され、非同期タスクが5秒間実行されると仮定すると、同時実行の問題が発生しますか?

これは内部でどのように機能しますか?asyncTaskFinished後に実行されますかfirstSelector、それとも実行のfirstSelectorために一時停止されますasyncTaskFinishedか?

実行ループとのリンクはありますか?メソッドはキューに追加されてから、呼び出すときに実行されますか?

道に迷いました :)

ありがとうございました。

4

2 に答える 2

1

UI がメイン ループで実行されている間、メイン実行ループでは実行されない非同期タスクが非同期で実行されます。Concurrency Programming Guideをご覧ください。

したがって、ここであなたの場合、同期時間がどれくらいかかるかはよくわかりません。10秒かかるかもしれないと仮定していますが、完全にはわかりません。したがって、この場合、ブロックを操作するか、メイン スレッドで非同期タスクが完了したときに asyncTaskFinished 関数をトリガーする方法を見つける必要があります。単純なブロック コールバックを定義し、非同期タスクが終了したときに関数をトリガーすることができます。

非同期タスクに GCD を使用すると、非常に簡単になります。あなたはこれだけのことをするでしょう。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self runMyAsyncTask];
        // trigger the main completion handler when this completed
        dispatch_async(dispatch_get_main_queue(), ^{
            [self asyncTaskFinished];
        });
    });

同時実行に NSThread を使用する場合、 performSelector:onThread: を使用して、非同期タスクが終了したときに完了セレクターをトリガーできます。簡単なケースとして、コールバック ハンドラを実装する方法を示します。このような関数を作成して、非同期タスクをトリガーすることができます。

-(void)launchAsyncTaskWithCompletionHandler:(void(^)(void))completionHandler{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self runMyAsyncTask];
        // trigger the main completion handler when this completed
        dispatch_async(dispatch_get_main_queue(), ^{
            completionHandler();
        });
    });
}

これを呼び出すのは比較的簡単です。

[self launchAsyncTaskWithCompletionHandler:^{
        [self asyncTaskFinished];
    }];

これは理解しやすく、コードをより明確にします。これがお役に立てば幸いです。

于 2012-12-03T10:53:44.890 に答える
0

スレッドの実行ループは、その入力ソースから順次 (非並行) 方式でタスクを実行します。firstSelectorしたがって、とasyncTaskFinishedが同じ実行ループ内で実行される限り、心配する必要はありません。これは、コールバックのセマンティクスに依存します。performSelector:onThread:withObject:waitUntilDone:非同期コールバック関数が正しいスレッドで実行されるようにするために、次のようなものを使用する必要がある場合があります。

于 2014-01-25T23:07:58.737 に答える