2011-06-08 35 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