2012-06-05 73 views
1

我有一个在设置为10值A,那么这段代码运行的NSTimer: [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]; 我的空虚这个样子的诠释未能做数学?

-(void)updateTimer { 
     timeLeft = timeLeft -0.01; 
     NSString *string = [NSString stringWithFormat:@"%i",timeLeft]; 
     [timer setString:string]; 
     NSLog(string); 

    } 

我使用Coco2D,这是没有问题的 在我登录它出来像这样

2012-06-05 17:28:56.030 NumberPop[31291:10a03] 9 
2012-06-05 17:28:57.030 NumberPop[31291:10a03] 8 
2012-06-05 17:28:58.030 NumberPop[31291:10a03] 7 
2012-06-05 17:28:59.030 NumberPop[31291:10a03] 6 
2012-06-05 17:29:00.030 NumberPop[31291:10a03] 5 
2012-06-05 17:29:01.030 NumberPop[31291:10a03] 4 
2012-06-05 17:29:02.030 NumberPop[31291:10a03] 3 
2012-06-05 17:29:03.030 NumberPop[31291:10a03] 2 
2012-06-05 17:29:04.029 NumberPop[31291:10a03] 1 
2012-06-05 17:29:05.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:06.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:07.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:08.030 NumberPop[31291:10a03] 0 
2012-06-05 17:29:09.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:10.030 NumberPop[31291:10a03] 0 
2012-06-05 17:29:11.029 NumberPop[31291:10a03] 0 
2012-06-05 17:29:12.029 NumberPop[31291:10a03] 0 

的0的继续进行下去永远。 我很迷茫,有什么帮助吗?

+0

我看不到停下来的条件。如果你指望减法完全停止在零,我会说你不明白浮点数是如何工作的。您不能将0.1精确地表示为二进制,就像您可以将1/3精确地表示为十进制一样。 – duffymo

回答

9

所以它很好奇你为什么要从int中减去.01。但是当你这样做时,结果会被截断为int。所以如果你从9中减去.01得到8.99,但是int不能存储8.99,所以它被存储为8,一旦你得到0,它就会做同样的事情。 0 - .01 = -0.01,它被截断为0.所以你总是会从这个任务中得到零。

相反,尝试这样的事:

timeLeft = timeLeft - 1;

甚至更​​好

timeLeft --;

上述任一将继续递减低于零的整数,恩:-1, -2,-3 ....当然,假设它是一个无符号整数(其中int是)。另外,如果您要将计时器停止为零,则需要在时间到达零时将其无效。在这里寻找更多的信息:https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html#//apple_ref/occ/instm/NSTimer/invalidate

基本上,做这样的事情:

timeLeft --; 
if (timeLeft <= 0) [timer invalidate]; 

有虽则了解一些重要的东西。 NSTimer不保证它会在您指定的时间间隔内完全被调用。基本上,它会检查每个运行循环是否应该启动,然后在适当的情况下执行。但是你永远不会比运行循环更频繁地触发NSTimer。这意味着如果运行循环比正常运行时间长或者您的时间间隔太短,它可能会在启动之前跳过几个间隔。因此,通过减少一个数字来计算'时间'(就像你似乎在做的那样)是行不通的。相反,你需要找到另一种方式,比如在启动计时器时设置一个启动NSDate变量,然后检查每个计时器的当前时间与开始时间的差距。

NSDate在计算中返回相当精细的粒度。所以,如果你把一个起始日期,你可以这样做,得到自该日的时间间隔:

NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:startDate];

NSTimeInterval是double。所以,你可以将其转换为一个像这样的字符串:

NSString *string = [NSString stringWithFormat:@"%f", interval];

或限制的小数位:

NSString *string = [NSString stringWithFormat:@"%.2f", interval];

这应该给你你在找什么。

+0

然后可以显示一个'罚款'计时器吗? – Sirens

+0

取决于你要找的'好'。一般来说,运行循环非常快,除非有大量的图形(或其他)处理。但是,如果是这样的话,你的显示屏无法跟上,所以这个问题是没有意义的。当屏幕只在每个循环更新一次时,更新标签,进度条等毫无意义。但我在.01运行一个计时器没有任何问题。也意识到.01是100帧每秒.....这是非常高的,通常是不必要的。 –

+0

我的意思是:我可以得到像10.900一样的定时器输出吗? – Sirens