防止 NSTimer 在后台应用程序中触发延迟

Prevent NSTimer firing delays in background app

我正在开发一个显示时钟和其他数据的 macOS 应用程序(我们称它为 "display app"),该应用程序由同一台机器上的另一个应用程序("control app")控制通过 TCP 连接。我注意到当显示应用程序空闲一段时间(> 60 秒)然后安排一个 NSTimer(间隔为 .2 秒)时,它需要 very 很长时间计时器第一次触发(在 6-10 秒的范围内,有时更长。)这主要发生在显示应用程序不是最前面的时候(因为控制应用程序是。)一旦计时器第一次触发,它就会工作正如预期的那样(在计时器中有一些小的预期延迟)一段时间。

但是当定时器长时间 运行 时(超过 5 分钟),在触发之间也有类似的极端延迟(也是 6-10 秒。)看起来像手动调度定时器

[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

稍微推迟了问题(使用 [NSTimer scheduledTimer...] 比手动将其添加到 runloop 时问题出现得更快。)

这会造成很多麻烦,因为时钟在那段时间没有更新。

我认为发生这种情况是因为 macOS 以某种方式考虑显示应用 "idle" 或 "inactive"。

有没有办法预防、控制或规避这种行为?

这是App Nap。显示应用可以执行以下操作来避免打盹:

id activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep reason:@"whatever"];

当它又可以允许午睡时,你应该这样做:

[[NSProcessInfo processInfo] endActivity:activity];