ech*_*avo 24 cocoa nsdate nstimer
我刚刚完成我的应用程序和beta测试发现秒表部分的一个错误...秒表使用一个nstimer进行计数并有一个用于存储圈数的表,但是当滚动表圈时手表停止或暂停并没有弥补失去的时间.
通过使用以下方式消除了停滞:
startingTime = [[NSDate date] timeIntervalSince1970];
Run Code Online (Sandbox Code Playgroud)
计算经过的时间.
但是我仍然使用NSTimer来触发每0.1秒,这意味着滚动仍然会使定时器停止,即使经过的时间最终会正确更新...并且将它与Apple秒表进行比较它让我想知道是否秒表有一个单独的线程,仅用于计算经过的时间.有谁知道这是怎么做的?
现在,使用Epoch以来的时间在某种意义上运作良好,但它使启动,停止和重新启动秒表的问题复杂化
当手表停止时,时间被存储并用于计算手表重新启动时的偏移量,但似乎有一些延迟时间,并且当手表重新启动时,时间会明显跳跃.
任何对根本原因或解决方案的想法都将非常感激.
Ash*_*ark 48
bbum的答案提供了一种更好的方法来设计你的应用程序,但如果你想让你的计时器触发,无论用户是否正在操作UI,你都需要将它添加到runloop的跟踪模式.
假设您正在为iPhone开发,那么该模式就是UITrackingRunLoopMode.如果您正在为Mac开发,则会有类似名称NSEventTrackingRunLoopMode.
NSRunLoop *runloop = [NSRunLoop currentRunLoop];
NSTimer *timer = [NSTimer timerWithTimeInterval:0.1 target:self selector:@selector(myTimerAction:) userInfo:nil repeats:YES];
[runloop addTimer:timer forMode:NSRunLoopCommonModes];
[runloop addTimer:timer forMode:UITrackingRunLoopMode];
Run Code Online (Sandbox Code Playgroud)
bbu*_*bum 22
如果事件循环未运行,则在事件循环再次运行之前,任何计时器都不会触发.即使事件循环不是阻塞,也不能保证定时器在其配置的间隔内正好触发.如果你的时间完全基于定时器开火,那么错误的数量会随着时间的推移而增加.
您需要与定时器的触发分开跟踪持续时间.每次计时器触发时,重新计算持续时间并重新显示.
对于开始/暂停/重启/停止类型的设置,您通常希望:
在启动时获取时间(作为NSDate实例或作为NSTimeInterval值)
暂停或停止时,暂停/停止时抓住时间.从此时间减去开始时间,您有间隔的持续时间
重新启动后,在重新启动时抓住时间,但也要保持已经过去的持续时间
在暂停/停止时,抓住暂停/停止时间并添加已经过去的持续时间
通常,使用NSTimeInterval值(只是双倍)执行所有这些操作是最简单的.但是,如果需要跟踪事件发生的实际时刻,请改用NSDate实例.