22

だから私は、後で呼び出すことで使用できるようにしたい新しい NSThread を開始していますperformSelector:onThread:...。私が理解している方法から、そのメソッドはその呼び出しをそのスレッドの実行ループに追加するため、次の反復でこれらの呼び出しをすべてポップし、呼び出すものがなくなるまで呼び出します。したがって、この種の機能が必要です。つまり、すぐに呼び出せる作業の準備が整ったアイドル スレッドです。私の現在のコードは次のようになります。

   - (void)doInitialize
   {
       mThread =  [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
       [mthread start];
   }

   - (void)runThread
   {
       NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

       // From what I understand from the Google machine is that this call should start the
       // runloop on this thread, but it DOESN'T. The thread dies and is un-callable
       [[NSRunLoop currentRunLoop] run];

       [pool drain];
   }

   - (void)scheduleSomethingOnThread
   {
       [self performSelector:@selector(hardWork) onThread:mThread withObject:nil waitUntilDone:NO];
   }

しかし、スレッドは維持されず、performSelector:onThread は何もしません。これを正しい方法で行うにはどうすればよいですか?

4

2 に答える 2

15

実行ループを実行するには、少なくとも 1 つの「入力ソース」が必要です。メインの実行ループはそうしますが、ソースを手動で追加して、セカンダリ実行ループの-runメソッドを取得して何かを実行する必要があります。これに関するドキュメントがいくつかありますhere

[[NSRunLoop currentRunLoop] run]これを機能させる単純な方法の 1 つは、無限ループに入れることです。何かすることがあればそれを実行し、それ以外の場合はすぐに戻ります。問題は、スレッドが何かが発生するのを待つだけでかなりの量のプロセッサ時間を消費することです。

別の解決策は、この実行ループに NSTimer をインストールして存続させることです。

ただし、可能であれば、このようなことのために設計されたメカニズムを使用する必要があります。可能であれば、NSOperationQueueバックグラウンド操作に使用することをお勧めします。

于 2011-06-08T01:06:13.190 に答える
10

このコードは、スレッドを永久に待機させる必要があります

BOOL shouldKeepRunning = YES;        // global
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; // adding some input source, that is required for runLoop to runing
while (shouldKeepRunning && [runLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); // starting infinite loop which can be stopped by changing the shouldKeepRunning's value
于 2013-02-25T16:34:29.113 に答える