NSTimer 可靠的替代方案

10

我有一个应用程序,需要每隔1秒记录一些信息,目前我正在使用NSTimer,但是如果我的应用程序切换屏幕或进行其他操作,会稍微减慢计时器速度,从而导致读数不准确。

有什么可靠的替代方案吗?我的当前代码如下:

timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(update) userInfo:nil repeats:YES];
2个回答

14

NSTimer不能保证精确按时触发。但您可以以比现在更可靠的方式使用NSTimer。当您使用 scheduledTimerWithTimeInterval 时,会创建一个被安排在NSDefaultRunLoopMode下运行循环中的NSTimer。当UI正在使用时,该模式会暂停,因此当用户交互时,您的计时器不会触发。为避免此暂停,请使用NSRunLoopCommonModes 模式。为此,您需要自行预定计时器,如下所示:

timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(update) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

好的,我现在会更改它。我是否以相同的方式“[timer invalidate]”使计时器无效? - Baub
以这种方式创建的计时器交互方式相同,只是您必须手动添加它。当您调用invalidate时,它应该自动从runloop中删除,就像以前一样。 - NJones

4
您可以:
  • 将NSTimer放在不同的线程中(这样可能不会受到UI的影响)
  • 减小间隔时间(比如0.1秒),并在您的日志函数中检查是否是记录所需的“正确”时间。

不是 NSTimer 会创建自己的新线程吗?只是问一下...我在某个地方看到过这样的说法。 - Ankit Srivastava
我尝试通过调用performSelectorInBackground将计时器放在不同的线程中,但当它触发时它不会调用选择器(我猜是因为它在不同的线程中)。 - Baub
2
@Steve:NSTimer 不会创建自己的线程,它运行在创建它的线程上。 - jscs
1
减小时间间隔是一个好的解决方案。NSTimer不是实时机制。 - jscs
也可以尝试使用Grand Central Dispatch(GCD)。它也可以用于创建定时器。也许它们会更可靠。 - Macmade

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接