任何人都知道为什么nextEventMatchingMask:untilDate:inMode:dequeue:需要很多ms才能返回一个事件?

时间:2009-06-12 04:41:03

标签: cocoa macos

在OS X游戏中,建议使用此方法来获取键盘和鼠标事件。

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for(;;)
{
    NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:nil inMode:NSDefaultRunLoopMode dequeue:YES];
    if(!event) break;
    processevent(event);
    ...
}
[pool release];

在游戏主循环(其跨平台)中调用。

由于OSX 10.5.X的最新版本,当有可用事件时,此调用会突然占用每个事件几毫秒,并且在事件出现时游戏的帧速率会受到影响。如果有多个事件,则在较慢的mac上每帧可能需要10毫秒。

任何人都知道为什么会这样?或者我可以做什么来获得事件而不会对游戏造成太大影响?

我尝试通过手动获取鼠标位置来自己管理鼠标事件,当它接近屏幕边缘时将其扭曲到中心,但这会导致动作出现故障(仅当光标被隐藏时) )。

其他替代方案可能是从HID经理那里得到的东西,我们已经为操纵杆做了什么,但是HID并不是非常清楚。

mac越快,获得事件的障碍就越明显。

3 个答案:

答案 0 :(得分:2)

我认为您需要在循环中释放并重新分配自动释放池:因为您拥有循环所有自动释放的项目正在构建并且永远不会被刷新。

答案 1 :(得分:1)

副手,我不知道为什么这个方法需要这么长时间才能返回。这值得调查cocoa-dev list或另一个Apple论坛资源。我的猜测是自己管理事件是一个坏主意 - AppKit已针对此进行了优化,您可以放心地下注它将比抛出自定义代码快得多。

然而,你可以采取一些措施来防止它影响你的游戏:把它放在一个单独的线程中。这是一种建议的方法,可以在长方法调用期间防止UI冻结。 Apple发布了Introduction to Threading programming guide,可以帮助您快速掌握所需的关键概念。

答案 2 :(得分:1)

我认为您必须在untilDate参数中使用实际值,例如[NSDate distantFuture][NSDate distantPast]。该函数将阻塞,直到前一种情况中的事件可用,而在后一种情况下它将立即返回nil事件。

我是从GLFW源代码中学到的。