2011-06-08 51 views
21

因此,我開始一個新的NSThread,我希望能夠稍後使用通過調用performSelector:onThread:...。根據我的理解,它調用方法將該調用添加到該線程上的runloop,因此在下一次迭代時,它將彈出所有這些調用,並隨後調用它們,直到沒有任何剩餘的調用。所以我需要這種功能,一個空閒的線程準備工作,我可以調用它。我目前的代碼如下所示:保持NSThread活着,並運行它的NSRunLoop

- (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不執行任何操作。我如何以正確的方式去做這件事?

回答

15

運行循環需要至少一個「輸入源」才能運行。主要的運行循環會執行,但您必須手動添加源以獲取輔助運行循環的方法來執行任何操作。這裏有一些關於這個here的文檔。

一個天真的方式來得到這個工作將只是把[[NSRunLoop currentRunLoop] run]在一個無限循環;當有事情要做時,它會做,否則立即返回。問題是線程會花費大量的處理器時間來等待某些事情發生。

另一種解決方案是在此運行循環中安裝NSTimer以保持其運行。

但是,如果可能的話,你應該使用爲這種事情設計的機制。如果可能,您可能需要使用NSOperationQueue進行後臺操作。

+0

謝謝,這是一個有點清晰了。 – ErikPerik 2011-06-08 01:43:31

+4

這對命令行工具中的主運行循環也是如此。它是NS/UIApplication,它在GUI應用程序的主運行循環中提供默認輸入源。 – 2011-06-08 02:13:51

8

這段代碼應強制線程永遠等待

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