NSTimer重复得太快了 [英] NSTimer repeating too fast

查看:153
本文介绍了NSTimer重复得太快了的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题

The Problem

我正在构建一个应用程序,我正在获取实时数据并更新的MKMapView。我每10秒获得一批数据,并且在来自Web服务的数据集之间,我正在删除旧数据点,同时还添加新数据点。

I am building an app where I am getting real-time data and updating a MKMapView. I get a batch of data every 10 seconds and between data sets from the webs service I am removing older data points while also adding the new ones.

而不是一次更新所有这些我想要分散我在10秒内从数据服务获得的新点的动画,所以我创建'实时'尽可能多地停下来,尽量避免。

Instead of updating them all at once I want spread out the animation of the new points I get from the data service over that 10 seconds so I create the 'real-time' feel and avoid as many stops and starts as I can.

除了NSTimer总是尽早完成之前,一切似乎都很有效。它应该在10秒内循环遍历新数据,但它通常会在4到5秒之前完成新数据集的循环。

Everything seems to be working great except the that the NSTimer is always finishing early... way early. It should loop through the new data over 10 seconds but it will typically finish looping through the new data set 4 to 5 seconds earlier then it should.

我已阅读了很多Apple文档和StackOverflow问题(以下是两个可能正在寻找的好问题):)

I have read through a lot of the Apple documentation and StackOverflow questions (below are two good ones for those that may be looking) :)

https://stackoverflow.com/a/18584973
https://developer.apple.com/library/ios/technotes/tn2169/_index.html#//apple_ref/doc / uid / DTS40013172-CH1-TNTAG8000

但似乎大部分建议都是针对使用 CADisplayLink的游戏应用程序(但我没有构建游戏应用程序)或者如果你需要使用高性能计时器,它不应该连续使用。

But it seems like most of the recommendations are made for gaming apps using CADisplayLink (but I am not building a gaming app) or that if you need to use a high performance timer that it should not be used continuously.

我的计时器不需要精确但如果我甚至可以在.5秒内得到它,这将是很好的,而不必添加一些其他选项的开销我见过。

My timer does not need to be exact but if I could even get it within .5 seconds that would be great without having to add the overhead of some of the other options I have seen.

一如既往,您可以指出我的任何想法/代码/指示将不胜感激。

As always any thoughts / code / or directions you could point me would be greatly appreciated.

代码

The Code

收藏后新数据到数组我创建时间间隔并使用下面的代码启动计时器

Once I collect the new data into arrays I create the time interval and start the timer with the code below

addCount = -1;
timerDelay = 10.0/[timerAdditions count];

delayTimer =[NSTimer scheduledTimerWithTimeInterval:timerDelay target:self selector:@selector(delayMethod) userInfo:nil repeats:YES];

然后激发此方法,通过添加和删除我的地图注释来激活动画。

That then fires this method that animates through adding and removing the my map annotations.

-(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];

}

}

更新

UPDATE

我尝试通过GCD更新我的计时器。奇怪的是,时序循环适用于所有其他数据集。仍然没有它每个领带工作,但由于某种原因它似乎与重置调度时间或计时器间隔有关。

I tried updating my timer through GCD. And what is odd is that the timing loop works every other dataset. Still do not have it working every tie but for some reason it seems to be tied to resetting the dispatch time or the timer interval.

 -(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];

    }

});


}


推荐答案

由于我在下面引用的另一个SO问题,我走了一条略有不同的道路。基本上通过将两个定时器组合成一个,将一个定时器设置为我需要的最快时间间隔,并且在定时器调用的方法中管理我需要的方法,我已经解决了我所看到的问题。

I went down a slightly different path thanks to another SO question I have referenced below. Basically by combining the two timers into one, setting that one timer to the fastest time interval I would need and managing the methods I need to at the changing intervals within the method called by the timer I have solved the problem I was seeing.

https://stackoverflow.com/a/25087473/2939977

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];

}

这篇关于NSTimer重复得太快了的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆