我在viewDidLoad方法中有以下代码。它所做的只是每秒更新一个标签。但是,当我运行此代码时,它显示虚拟文本,稍等一下,然后显示8秒而不是9,然后是8 ..
所以看起来它正在跳过9,是否有可能解决这个问题?在计算剩余时间时,我是否应该舍入小数?
感谢您的时间!
//Just dummy text
self.lblTime.text = @"Tid: 0h 0min 10sec";
NSDate *expireDate = [[NSDate alloc] initWithTimeInterval:10 sinceDate:[NSDate date]];
self.expires = expireDate;
[expireDate release];
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimerDisplay) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:UITrackingRunLoopMode];
在updateTimerDisplay中我有:
//Gets the time right now
NSDate *now = [NSDate date];
//Stores the difference in seconds between when the test was started and now.
NSTimeInterval interval = [self.expires timeIntervalSinceDate:now];
//Gets the number of hours
NSInteger hours = interval / 3600;
interval = (int)interval % 3600;
//Gets the number of seconds
NSInteger minutes = interval / 60;
interval = (int)interval % 60;
NSInteger seconds = interval;
//Updates the label
self.lblTime.text = [NSString stringWithFormat:@"Time: %dh %dmin %dsec", hours, minutes, seconds];
答案 0 :(得分:2)
NSTimer
无法保证在正确的时间间隔内完全启动。你可以确定的唯一一点就是定时器不会过早启动(假设你的设备的时钟以准确的速度运行),但它很可能会发射得太晚。
在你的情况下,即使计时器发出的时间太晚,你也会得到错误的结果,因为你没有四舍五入seconds
值,你只是截断它。您应该考虑舍入seconds
和/或更频繁地启动计时器(例如每0.2或0.1秒)。
答案 1 :(得分:1)
首先,我建议使用[NSDate dateWithTimeIntervalSinceNow:10]
代替[[NSDate alloc] initWithTimeInterval:10 sinceDate:[NSDate date]]
和[self.expires timeIntervalSinceNow]
代替[self.expires timeIntervalSinceDate:[NSDate date]]
。这些更简洁。
另请注意,由于self.expires
在第二组代码中的日期早于now
,因此interval
将否定,因为间隔因为 now
实际上是self.expires
以来的间隔。您的代码似乎没有考虑到这一事实。
最后,如果你将expires
设置为将来10秒,然后让你的计时器在一秒钟内开启,你可能已经错过了9秒的标记。这是因为所有计时器本质上都不是100%准确,因此可能已经过了略多于1秒。假设已经过了1.01秒,那么剩下10 - 1.01 = 8.99秒,使用整数数学将被截断为剩余8秒。这在我看来是导致你的错误。我通常建议每隔一秒(每十分之一秒左右)更频繁地触发你的计时器以避免这些问题。
如果您有兴趣,这是temporal aliasing的一个例子。