2

たとえば、2つのスレッドがあり、1つはメインスレッドで、もう1つはセカンダリスレッドです。メインスレッドが最も使用されていますが、(まれに)メインスレッドからの呼び出しに基づいてセカンダリスレッドに何らかの作業を実行させたい場合があります。ほとんどの場合、セカンダリスレッドはスリープする必要があります。いくつか検索した後、これを行う方法はrunLoopsを使用することであることがわかりました。だから私はアップルのドキュメントを読んでみました(http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW5)。

しかし、それは私には非常に複雑に見え、私はそこで少し苦労しています。私が説明したことを達成するためのエレガントでシンプルな方法はありますか?実行して遊ぶことができる同様のrunLoopコード例はありますか?

ありがとう

4

3 に答える 3

5

各スレッドには実行ループがあります。

各実行ループには、実行する必要のあるもののリストがあります。これらはすべて実行ループで「スケジュール」されていると言われますが、すべてが特定の日時にスケジュールされているわけではありません。

  • タイマーはです。
  • ソースはそうではありません。彼らは通常、Machカーネルポートまたはファイル記述子をノックする何かが来るのを待ちます。

実行ループが実行されているときは、通常は実行されていません。つまり、スレッドはスリープ状態であり、CPUサイクルを消費していません。(サンプリングすると、プロセスがスタックしているように見えますmach_msg_trap。これは「何かが起こるのを待つ」システムコールです。)カーネルは、mach_msg_trap何かが発生したときにスレッドをウェイクアップします(これにより、から戻ります)。スレッドの実行ループが処理する必要がある場合があります。

説明したことを正確に実行する方法は、実行ループソースを実装することです。セカンダリスレッドの実行ループでソースをスケジュールし、作業を実行してソースを実装し、実行する作業があるときにプライマリスレッドからソースを通知します。

ただし、NSOperationは、説明したケースに合わせて設計されているため、ほぼ確実に優れたソリューションです。一度に最大N(選択して少なくとも1つ)まで、シリアルに実行する必要のある個別の作業単位。

NSOperationQueueはスレッドを再利用するため、必ずしもすべての操作に対して新しいスレッドを作成するわけではないことに注意してください。確かに、それを行わないことがポイントの一部です。それはスレッドを怠惰に作成し、何もしていないすでに持っているものを使用します。

于 2010-09-22T21:29:12.020 に答える
4

これは、NSOperation/NSOperationQueueが作成されたようなもののように聞こえます。たまに「作業単位」しかない場合は、それらを操作して、完了を監視し、それに応じてUIを更新してみませんか?

于 2010-09-22T14:25:31.670 に答える
2

Matt Gallagherのブログ記事では、セカンダリスレッドのアプローチとバックグラウンド作業を行う他の方法を比較しています。

http://cocoawithlove.com/2010/09/overhead-of-spawning-threads.html

あなたの場合、スレッド作成のオーバーヘッドを気にする必要はありません。しかし、Mattのコード例は、セカンダリスレッドの実行ループを管理するための洞察を提供する可能性があります。

そうは言っても、私はJoshuaのアドバイスに従い、NSOperationQueueとNSOperationを使用してバックグラウンド作業を行います。作業をNSInvocationにカプセル化できる場合は、NSInvocationOperationを使用して、NSOperationサブクラスを回避できます。

于 2010-09-22T16:06:20.417 に答える