长话短说,我正在尝试创建一个简单的控制台游戏,允许用户将命令输入控制台以执行操作(例如启动/停止),同时打印出各种属性和操作进入控制台。
_gameDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(_gameDispatchQueue, ^{
_propertyTimer=[NSTimer scheduledTimerWithTimeInterval: 0.1
target: mairne
selector: @selector(printProperties:)
userInfo: nil
repeats: YES];
[[NSRunLoop currentRunLoop] run];
});
在我的main.mm文件中,我通过cin
接受输入,然后在输入时接受输入。
我对这段代码的问题在于,尽管我试图将它放在后台线程中,但它仍然不允许用户输入任何内容并按Enter键。因此,例如,如果他们想要编写stop
并按Enter键,则不会处理该命令。
如何让NSTimer在后台打印时运行,但仍允许处理用户输入?
答案 0 :(得分:2)
尝试在主线程上运行计时器但在选择器printProperties中运行,让它在调度队列中运行所有内容,如下所示:
// Init these somewhere on the main thread
_bgQueue = dispatch_queue_create("com.yourco.yourapp.bgQueue", NULL);
_propertyTimer=[NSTimer scheduledTimerWithTimeInterval: 0.1
target: mairne
selector: @selector(printProperties:)
userInfo: nil
repeats: YES];
- (void)printProperties:(id)sender
{
dispatch_async(_bgQueue, ^{
// do your work here
}
}
答案 1 :(得分:1)
为了进一步扩展bbum的答案,NSFileHandle
实际上有一个很好的Objective-C API,用于设置dispatch_source
。
您可以像NSFileHandle
一样获得stdin
:
NSFileHandle *standardInputHandle = [NSFileHandle fileHandleWithStandardInput];
NSFileHandle
有一个名为readabilityHandler
的属性,它会在数据进入时调用(异步)块。所以,你可以这样做:
standardInputHandle.readabilityHandler = ^(NSFileHandle *fileHandle) { handleUserInputData([fileHandle availableData]); };
假设您可以/想要逐行处理传入数据(即返回/换行始终是命令的结尾),这可能会对您有效。
答案 2 :(得分:1)
尝试将ncurses用于此类控制台应用程序是值得的。 getch
nodelay
用作非阻止键输入。
void initialize_function() {
nodelay(stdscr, TRUE);
}
void function_will_be_called_from_NSRunLoop() {
int ch;
if ((ch = getch()) != ERR) {
/*
* user has pressed a key ch, pool it into a queue for parsing command
* like start, stop, or something like that
*/
}
/*
* print out various properties and actions into the ncurses screen (the console)
*/
}
答案 3 :(得分:0)
将读数从stdin
移开主线程。或者,可能使用附加到dispatch_source
文件句柄的stdin
在数据可用时提供回调(缓冲可能很棘手)。