0

我正在为 Mac OS X 制作一个 CLI 工具,我的主要看起来像这样:

int main(int argc, const char * argv[]){

    @autoreleasepool {

        //Some startup stuff here
        [ServerPool sharedPool]; //Start the pool

        /*
         UI stuff for cli version
         */
        while (1){
            [[CLIUI sharedCLI] mainMenu];
            [[CLIUI sharedCLI] menuInput];
        }

    }
    return 0;
}

在代码的另一部分中,我正在启动一个 NSTimer

progressUpdateTimer = [NSTimer timerWithTimeInterval:1.0
                                              target:self
                                            selector:@selector(updateProgress:)
                                            userInfo:nil
                                             repeats:YES];

[[NSRunLoop currentRunLoop] addTimer: progressUpdateTimer forMode:NSDefaultRunLoopMode];

但是,它永远不会触发选择器 updateProgress:。我相信这是因为我的主目录中没有建立 NSRunLoop,对此有什么正确的解决方法?

4

1 回答 1

1

除非运行循环正在运行,否则计时器和其他任何依赖于运行循环的东西都不会触发。

在命令行程序中,您最好使用dispatch_main()GCD 并将控制权传递给 GCD ,或者在适当的模式下运行[NSThread currentRunLoop]适当的时间。

你将不得不摆脱它,while(1)因为它会阻塞运行循环。

并发编程文档包含有关如何使用运行循环的大量文档。

如果您确实需要该while循环,请将其移至第二个线程(主线程上的 NSRunLoop 更容易处理)并在主线程上运行运行循环。


您需要while(1)用 NSRunLoop 替换该循环。这也可能意味着您需要将输入代码更改为 adispatch_sourceNSFileHandle正在读取的astdin等...

即你将不得不重构你的代码相当多。谷歌搜索“在命令行程序中使用 nsrunloop”之类的内容,您可能会得到很多提示。同样,NSRunLoop 文档指向了一堆示例。

这可能看起来令人生畏,但一旦你了解 NSRunLoops,它们就是非常强大的构造。

于 2013-06-01T21:49:09.367 回答