別のスレッドで実行されているiphone ios


96

別のスレッドでコードを実行する最良の方法は何ですか?それは...ですか:

[NSThread detachNewThreadSelector: @selector(doStuff) toTarget:self withObject:NULL];

または:

    NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
                                                                        selector:@selector(doStuff:)
                                                                          object:nil;
[queue addOperation:operation];
[operation release];
[queue release];

私は2番目の方法を行っていますが、私が読んでいるウェズリークックブックでは最初の方法を使用しています。

回答:


243

私の意見では、最良の方法はlibdispatch、別名Grand Central Dispatch(GCD)を使用することです。iOS 4以上に制限されますが、とてもシンプルで使いやすいです。バックグラウンドスレッドで処理を行ってから、メインの実行ループで結果を使って何かを行うコードは、非常に簡単でコンパクトです。

dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // Add code here to do background processing
    //
    //
    dispatch_async( dispatch_get_main_queue(), ^{
        // Add code here to update the UI/send notifications based on the
        // results of the background processing
    });
});

まだ行っていない場合は、WWDC 2010のlibdispatch / GCD / blocksのビデオを確認してください。


3.0互換性が必要です:(
Mike S

1
その場合、操作キューはおそらく次善のソリューションです。また、同時実行性にあまり早く飛び込まないようにしてください。シングルスレッドでプロファイルを作成することから始めて、マルチスレッドにする必要があるかどうか、またはシングルスレッドコードをそれ自体でより効率的になるように設計できるかどうかを確認してください。単純なタスクの場合、performSelector:withObject:afterDelay:を使用して必要なことをすべて実行できる場合があり、マルチスレッドプログラミングに伴うすべての問題を回避できます。
ジャック、

これを後で復活させて申し訳ありませんが、performSelector:withObject:afterDelayを使用してメソッド呼び出しを生成した場合でも、非同期メソッド内でNSAutoReleasePoolを使用する必要がありますか?メインの自動解放プールを魔法のように使用する場合は、performSElector:afterDelayの方が間違いなく速いオプションです。
Mike S

いいえ、メソッドは独自の自動解放プールを持つメインスレッドで実行されているためです。
ジャック

4
@Joeすでに知っていることを言うリスクがありますが、スレッドを強制終了するコードを書く習慣を身につけるべきではありません。それは、長期的にはあなたやあなたのキャリアを助けません。スレッドを強制終了しない理由については、この投稿(または多くの類似記事)を参照してください。
MikeC 2012年

1

iOSでのマルチスレッド化に最適な方法は、GCD(Grand Central Dispatch)を使用することです。

//creates a queue.

dispatch_queue_t myQueue = dispatch_queue_create("unique_queue_name", NULL);

dispatch_async(myQueue, ^{
    //stuffs to do in background thread
    dispatch_async(dispatch_get_main_queue(), ^{
    //stuffs to do in foreground thread, mostly UI updates
    });
});

0

私は人々が投稿したすべてのテクニックを試してみて、どれが最も速いかを見てみますが、これはそれを行うための最良の方法だと思います。

[self performSelectorInBackground:@selector(BackgroundMethod) withObject:nil];

これにより、スレッドが低い優先度で起動されます。スレッド化には、gcdの使用が最良の方法です。
Karsten

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.