在我的应用程序中,我使用下面的代码,其间隔等于1.0f/30.0f
,这意味着每秒调用30次来调用incrementSpeed
。我在日志文件中注意到moduloResult
的值等于'0'一秒钟,incrementSpeed
每5秒调用30次,但我希望它每次调用它只需1次5秒。
- (void)move:(NSTimer *)theTimer {
// ...
CGFloat moduloResult = (float)((int)time % (int)5);
NSLog(@"mod = %f",moduloResult);
if (!moduloResult) {
[self incrementspeed];
}
//...
}
- (void)inctime:(NSTimer*) thetimer{
time = time + 0.10f;
timeLabel.text = [NSString stringWithFormat:@"%0.1f", time];
}
- (void)initializeTimer:(float)intero {
self.myTimer = [NSTimer scheduledTimerWithTimeInterval:intero target:self
selector:@selector(move:) userInfo:nil repeats:YES];
}
- (void)initializeTime {
float theInter = 1.0f/10.0f;
self.timescore = [NSTimer scheduledTimerWithTimeInterval:theInter target:self
selector:@selector(inctime:) userInfo:nil repeats:YES];
}
-(void)incspeed{
deno += 0.01f;
[fadeTimer invalidate];
self.fadeTimer = nil;
[self settheInterval:1.0f/deno];
[self initializeTimer:[self gettheInterval]];
NSLog(@"deno = %f", deno);
NSLog(@"interv = %f", theInterval);
}
答案 0 :(得分:1)
我不确定我是否完全明白你要做的是什么,但我可以说的是,当你处于精确度的边缘时,定时器的行为可能有点不可预测。而你正在这样做。 Here from the manual:
由于各种输入源a 典型的运行循环管理, 有效解决时间问题 计时器的间隔限制为开启 50-100毫秒的顺序。如果一个 计时器的发射时间发生在 长标注或运行循环时 在一种不监控的模式下 计时器,直到计时器才开火 下次运行循环检查时 计时器。因此,实际时间在 计时器可能发射的是什么 是一段很长的一段时间 预定的开火时间。
首先,你不可能有一个每1/30秒运行一次的计时器。即使是1/10秒,这就是你在代码中所说的,也是可能的边缘。
另请注意,计时器仍然会闪光,即使它已经很晚了。这可以解释为什么你会在你想到它之后看到计时器开火。
答案 1 :(得分:1)
通过self.timescore
,inctime:
每秒调用10次。每次,它将时间变量递增0.1秒。所以时间变量是自计时器开始以来的秒数,四舍五入到最接近的0.1秒。例如。如果你这样做,你会得到同样的结果:
... elsewhere ...
@property (nonatomic, assign) NSTimeInterval startTime;
- (void)initializeTime
{
self.startTime = [NSDate timeIntervalSinceReferenceDate];
}
- (void)move:(NSTimer *)theTimer
{
NSTimeInterval timeSinceInitializeTimeWasCalled =
[NSDate timeIntervalSinceReferenceData] - self.startTime;
// round down the nearest multiple of 0.1 if necessary, e.g.
timeSinceInitializeTimeWasCalled -=
fmod(timeSinceInitializeTimeWasCalled, 0.1);
}
这一行:
CGFloat moduloResult = (float)((int)time % (int)5);
在您声明的方法中调用每秒调用30次。鉴于它是正的,(int)时间将'时间'向下舍入到最接近的整数。因此moduloResult将为'0'30次 - 在进入第五秒之间并再次退出之间。正如我在上面发布的代码中暗示的那样,您可能想要的是:
CGFloat moduloResult = fmod(time, 5.0);
即便如此,您也不希望将结果直接与0进行比较,因为浮点数往往会以不精确的方式进行舍入。如果您每秒呼叫该方法30次,我建议:
CGFloat moduloResult = fmod(time + 1.0 / 60, 5.0);
if(moduloResult < 1.0 / 30.0)
{
}
因此,当时间模式5为零时,您正在检查时间是否在1/30周围。
答案 2 :(得分:0)
如果将float或double转换为int,则会删除其小数。所以时间只是一个整数。所以它总是将整数除以5,这意味着你永远不会有模数。你为什么实际将它们转换为整数?尝试将它们都加倍,看看是否有帮助。可能会弄错,但我认为它会起作用。