在“类似秒表”的 NSTimer 期间,0:02 处出现一致的 1 秒长延迟应用程序
我有一个应用程序,它使用秒表式的从 0 开始计数的 HH:mm:ss 格式。该代码对我来说看起来非常简单,而且我想不出更有效的方法来运行它。
由于某种原因,当我运行它时,当计时器到达 00:00:02 时,会出现非常明显且一致的滞后(每次我在同一个地方运行它)。它会在 00:00:02 停留整整一秒,然后正常计数。为什么会出现这种情况呢?
-(IBAction)startAndStop;
{
if (!timer) {
NSLog(@"Pressing Start Button");
[startAndStopButton setTitle:@"Stop" forState:0];
startDate = [[NSDate date] retain];
timerLabel.text = @"00:00:00";
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(timerStart)
userInfo:nil
repeats:YES];
} else {
NSLog(@"Pressing Stop Button");
[startAndStopButton setTitle:@"Start" forState:0];
[startDate release];
[timer invalidate];
timer = nil;
[timer release];
}
}
-(void)timerStart
{
NSDate *currentDate = [NSDate date];
NSTimeInterval countInSeconds = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSinceReferenceDate:countInSeconds];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"HH:mm:ss"];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [df stringFromDate:timerDate];
[df release];
timerLabel.text = timeString;
}
I have an app that uses a stopwatch-style count up from 0 in HH:mm:ss format. The code looks pretty straightforward to me, and I can't think of a more efficient way to run it.
For some reason, when I run it, there is a very noticeable and consistent (every time I run it, in the same place) lag when the timer gets to 00:00:02. It stays on 00:00:02 for a full second, and then counts on normally. Why would this happen?
-(IBAction)startAndStop;
{
if (!timer) {
NSLog(@"Pressing Start Button");
[startAndStopButton setTitle:@"Stop" forState:0];
startDate = [[NSDate date] retain];
timerLabel.text = @"00:00:00";
timer = [NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(timerStart)
userInfo:nil
repeats:YES];
} else {
NSLog(@"Pressing Stop Button");
[startAndStopButton setTitle:@"Start" forState:0];
[startDate release];
[timer invalidate];
timer = nil;
[timer release];
}
}
-(void)timerStart
{
NSDate *currentDate = [NSDate date];
NSTimeInterval countInSeconds = [currentDate timeIntervalSinceDate:startDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSinceReferenceDate:countInSeconds];
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"HH:mm:ss"];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [df stringFromDate:timerDate];
[df release];
timerLabel.text = timeString;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
NSTimer 不会在精确的时间或时间间隔触发(检查规范以了解可能的错误)。因此,在同一时钟秒内,当四舍五入到最接近的秒时,可能会发生一次延迟触发和一次提前触发,并且您将看到口吃效果。
相反,使用更快的计时器(或 CADisplaylink),例如 30 Hz,检查时间,并仅在时间变化足以更改标签(一秒)时更新标签。
NSTimer does not fire at exact times or time intervals (check the specification for the likely error). Thus it is possible for one late firing and one early firing to occur during the same clock second, when rounded to the nearest second, and you will see a stutter effect.
Instead, use a much faster timer (or CADisplaylink), say at 30 Hz, check the time, and update the label only if the time has changed enough to change the label (one second).
您传递的时间间隔以秒为单位:
我的猜测是它立即被调用,然后每 1 秒调用一次,因为您将 1 秒作为计时器间隔。尝试传递 1.0/20.0 之类的值以更高的帧速率进行更新。
The interval you are passing is in seconds:
My guess is that it is getting called immediately, and then every 1 second afterwards, since you are passing 1 second as the timer interval. Try passing something like 1.0/20.0 to update at a higher frame rate.