当float为0时停止NSTimer

时间:2011-03-06 22:58:25

标签: objective-c ios4 floating-point nstimer

我有一个NSTimer和一个显示秒数倒计时的标签。

-(void)start {

myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(showActivity) userInfo:nil repeats:YES];

}

- (IBAction)停止{

[myTimer invalidate];

}

- (void)showActivity {

currentTime = [timeLabel.text floatValue];
currentTime -= 0.01;
timeLabel.text = [NSString stringWithFormat:@"%.2f", currentTime];  

if (currentTime == 0) {

    [self stop];

    ResultViewController *screen = [[ResultViewController alloc] initWithNibName:nil bundle:nil];
    screen.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
    [self presentModalViewController:screen animated:YES];
    [screen release];
}

}

- (void)viewDidLoad {
[super viewDidLoad];
timeLabel.text = @"60.0";
[self start];

}

因此,当时间为0时,计时器应该停止并且ResultViewController应该加载,但是当我这样做时,计时器仍然会倒计数到负数而没有任何反应。

有没有人可以帮助我?

谢谢:)

6 个答案:

答案 0 :(得分:2)

0.01没有精确的浮点二进制表示,因此你的浮点数永远不会精确为零。在比较中使用< =而不是==。

答案 1 :(得分:0)

浮点运算通常不是“精确的”(参见http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems)。将支票更改为if (currentTime <= 0.0),您就可以了。

答案 2 :(得分:0)

尝试这样的事情:

if(currentTime <= 0.0)
     ...

你所遭受的是浮点漂移。这是一个众所周知的现象。

答案 3 :(得分:0)

并非所有数字都可以使用浮点变量准确存储。正如1/3不能用基数10中的有限数字表示,1/10不能用基数2中的有限数字表示。最终得到的是舍入到0.10000000000000001或接近。因此,当你从中减去0.1时,你就不会得到0。

对此最有力的解决方案是将您的时间以毫秒存储在整数中,并在您想要更新标签时将其除以。不要打扰从标签到数字来回。数字的规范存储应该是一个数字。标签只是为了显示它。

修改

对于每个人都建议他改为<=而不是 - 这只是一个几乎没有被掠夺的黑客。浮点表示为0.1通常为0.10000000000000001。当你从中减去0.1时会发生什么?它仍然高于0.条件仅在达到-0.1时触发,这不是应用程序的预期行为。这是一个糟糕的解决方案。

答案 4 :(得分:0)

ResultViewController应该只分配init而不是将alloc initWithNibName设置为nil。

当前时间比较应设为if (currentTime <= (float)0.0)或类似(原因参见:this thread

答案 5 :(得分:-1)

最好不要与int进行比较。尝试这样做:

if (currentTime == 0.0) {