Objective c 防止后台应用程序中的NSTimer触发延迟

Objective c 防止后台应用程序中的NSTimer触发延迟,objective-c,macos,cocoa,nstimer,Objective C,Macos,Cocoa,Nstimer,我正在开发一个macOS应用程序(我们称之为“显示应用程序”),它显示时钟和其他数据,由同一台机器上的另一个应用程序(“控制应用程序”)通过TCP连接控制。我注意到,当显示应用程序空闲一段时间(>60秒),然后安排一个NSTimer(间隔为.2秒)时,计时器第一次启动(在6-10秒范围内,有时更长)需要很长时间。这种情况主要发生在显示应用程序不是最前面的时候(因为控制应用程序是最前面的)一旦计时器第一次启动,它将按预期工作一段时间(计时器中有一些小的、预期的延迟) 但是,当计时器运行很长时间(超

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

但是,当计时器运行很长时间(超过5分钟)时,两次触发之间也会出现类似的极端延迟(也就是6-10秒)。这看起来像是手动使用

[[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
将问题推迟一点(使用
[NSTimer scheduledTimer…]
使问题比手动将其添加到runloop时出现得更快。)

这会造成很多麻烦,因为时钟在此期间没有更新

我认为这是因为macOS在某种程度上认为显示应用程序“空闲”或“不活动”

有什么方法可以防止、控制或规避这种行为吗?

这是。display应用程序可以执行以下操作以避免打盹:

id activity = [[NSProcessInfo processInfo] beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep reason:@"whatever"];
当它允许再次小睡时,您应该执行以下操作:

[[NSProcessInfo processInfo] endActivity:activity];

使用
NSTimer
(文档在这一点上非常清楚)基本上没有时间保证。考虑使用宏大中心调度作为您的时序机制,像这可能是。您可以尝试使用选项进行显示应用程序调用
[[NSProcessInfo processInfo]beginActivityWithOptions:NSActivityUserInitiatedAllowingIdleSystemSleep reason:@“任意”]@Kenthomass谢谢,这正是问题所在。如果你把它作为一个答案,我会接受的…@JamesBucanek谢谢,我知道计时器不能保证精确,但这里的问题显然超出了正常的计时器延迟-时间差达到5000%。这个问题确实是由App-Nap引起的。@JamesBucanek这是一个多么“有启发性”的评论——是的,人们很清楚,没有时间保证,但在几毫秒和10秒之间存在差异。