Ios7 n计时器重复得太快
问题 我正在构建一个应用程序,从中获取实时数据并更新MKMapView。我每10秒获得一批数据,在Web服务的数据集之间,我删除旧的数据点,同时添加新的数据点 我不想一次更新所有数据点,而是希望将从数据服务获得的新点的动画在10秒内展开,这样我就可以创建“实时”感觉,并尽可能避免多次停止和启动 除了NSTimer总是提前完成之外,一切似乎都很顺利。。。太早了。它应该在10秒内循环新数据,但通常会提前4到5秒完成新数据集的循环 我已经阅读了很多苹果的文档,下面的StackOverflow问题对于那些可能正在寻找的人来说是两个很好的问题: 但似乎大多数建议都是针对使用CADisplayLink的游戏应用程序提出的,但我不是在构建游戏应用程序,或者如果需要使用高性能计时器,则不应连续使用 我的计时器不需要精确,但如果我能在0.5秒内完成,那就太好了,而不必增加我见过的其他一些选项的开销 和往常一样,如果您能给我提供任何想法/代码/或方向,我将不胜感激 代码 一旦我将新数据收集到数组中,我就会创建时间间隔,并用下面的代码启动计时器Ios7 n计时器重复得太快,ios7,mkmapview,nstimer,mkannotationview,Ios7,Mkmapview,Nstimer,Mkannotationview,问题 我正在构建一个应用程序,从中获取实时数据并更新MKMapView。我每10秒获得一批数据,在Web服务的数据集之间,我删除旧的数据点,同时添加新的数据点 我不想一次更新所有数据点,而是希望将从数据服务获得的新点的动画在10秒内展开,这样我就可以创建“实时”感觉,并尽可能避免多次停止和启动 除了NSTimer总是提前完成之外,一切似乎都很顺利。。。太早了。它应该在10秒内循环新数据,但通常会提前4到5秒完成新数据集的循环 我已经阅读了很多苹果的文档,下面的StackOverflow问题对于那
addCount = -1;
timerDelay = 10.0/[timerAdditions count];
delayTimer =[NSTimer scheduledTimerWithTimeInterval:timerDelay target:self selector:@selector(delayMethod) userInfo:nil repeats:YES];
然后激发此方法,该方法通过添加和删除“我的地图”注释来设置动画
-(void) delayMethod {
addCount = addCount +1;
if (addCount >= [timerAdditions count]) {
[timerRemovals removeAllObjects];
[timerAdditions removeAllObjects];
addCount = -1;
[delayTimer invalidate];
delayTimer = nil;
} else {
[myMap addAnnotation:[timerAdditions objectAtIndex:addCount]];
[myMap removeAnnotation:[timerRemovals objectAtIndex:addCount]animated:YES];
}
}
更新
我试着通过GCD更新我的计时器。奇怪的是,定时循环每隔一个数据集工作一次。仍然没有让它在每一条领带上都起作用,但出于某种原因,它似乎与重置调度时间或计时器间隔有关
-(void) delayMethod {
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * timerDelay); // How long
dispatch_after(delay, dispatch_get_main_queue(), ^(void){
addCount = addCount +1;
if (addCount >= [timerAdditions count]) {
[timerRemovals removeAllObjects];
[timerAdditions removeAllObjects];
addCount = -1;
//[delayTimer invalidate];
//delayTimer = nil;
} else {
NSLog(@"Delay fired count %i -- additoins %lu",addCount,(unsigned long)[timerAdditions count]);
[myMap addAnnotation:[timerAdditions objectAtIndex:addCount]];
[myMap removeAnnotation:[timerRemovals objectAtIndex:addCount]animated:YES];
[self delayMethod];
}
});
}
我使用定时器,就像这样做的东西与定时器实例更准确的结果
- (void)createTimer {
// start timer
if(gameTimer == nil)
gameTimer = [NSTimer timerWithTimeInterval:1.00 target:self selector:@selector(timerFired:) userInfo:nil repeats:YES] ;
[[NSRunLoop currentRunLoop] addTimer:gameTimer forMode:NSDefaultRunLoopMode];
timeCount = 725; // instance variable or you can set it as your need
}
- (void)timerFired:(NSTimer *)timer {
// update label
if(timeCount == 0){
[self timerExpired];
} else {
timeCount--;
if(timeCount == 0) {
// display correct dialog with button
[timer invalidate];
[self timerExpired];
}
}
//do your stuff here for particular time.
}
- (void) timerExpired {
// display an alert or something when the timer expires.
NSLog(@"Your time is over");
[gameTimer invalidate];
gameTimer = nil;
//do your stuff for completion of time.
}
在这段时间间隔内,您需要。而且还可以根据需要增减。并在计时器启动并完成的情况下进行操作。在您的情况下,如果您不想使计时器过期,则可以。永远不要使计时器实例无效,只使用计时器触发的事件来做事情。由于下面提到的另一个问题,我走了一条稍微不同的道路。基本上,通过将两个计时器组合为一个,将一个计时器设置为我需要的最快时间间隔,并在计时器调用的方法中按不断变化的时间间隔管理我需要的方法,我已经解决了我看到的问题
如果您将timerDelay设置为1.0之类的值,是否会看到计时器每隔1秒或更频繁/更少地触发一次?您确定timerAdditions包含它应该包含的数字吗?@NG。如果我将timerDelay固定为1.0,它将以正确的时间间隔正确运行第一批数据,但在下一批数据启动后,它开始以4到5秒的速度运行每批数据。我已经检查了timerAdditions,它确实包含我认为应该添加的ifdaytimer==nil{delayTimer=[NSTimer scheduledTimerWithTimeInterval:timerDelay目标:self selector:@selectordelayMethod userInfo:nil repeats:YES];}@Max则时间间隔不会随我每10秒接收的新数据集而改变,并且由于数据量会随每批而改变,因此我需要时间间隔相对于数据集大小而改变,即,如果我得到10个数据点,我需要方法每1秒运行一次,但如果我得到20个数据点,我需要方法每0.5秒运行一次秒。你没有提到1秒和0.5秒。当您需要更改计时器间隔时,请先使其无效,然后将其设为零。然后重新开始新的时间间隔。这与我当前代码中的路径相同。。。问题发生在我完成第一个数据集循环之后,我需要将时间重置为新的时间间隔,该时间间隔在我完成第一个循环之后立即发生。您是在代码中这样做,还是只是在运行它直到timeCount==0?timeCount是我需要使用它来做的,对于您的情况,您可以为您的新计时器调用create timer,或者在我的代码中,当timeCount=0时,您可以在使其为nil和invalidate之后使用新值再次调用它。
timeAdder = (10.0/[timerAdditions count]);
timeCountAnimate = timeAdder;
[NSTimer scheduledTimerWithTimeInterval:0.11 target:self selector:@selector(timerFired) userInfo:nil repeats:YES];
- (void)timerFired {
timeCount += 0.111;
if (timeCount > 10.0) {
// call a method to start a new fetch
timeCount = 0.0;
timeCountAnimate =0.0;
[self timerTest];
}
if (timeCount > timeCountAnimate) {
timeCountAnimate += timeAdder;
[self delayMethod];
}