为什么在主队列中运行NSTimer循环时,活字节会不断上升?

时间:2014-07-02 21:44:35

标签: ios multithreading nstimer dispatch

我搜索过StackOverflow类似的主题;有两个类似的帖子,但我有点虚拟,不明白给出的答案。我的问题是,当我运行此代码而未指定它应该在调度队列上时,实时字节稳定下来并且不会继续增加,但是当我指定它应该在调度队列上时,实时字节最终会通过屋顶。

之间发生的事情

//这里有很多东西

//在这里完成很多东西

非常重,所以我不希望它在主线程上:我希望结果能够为算法的其余部分提供持续的更新。此外,当调度线被注释掉时,我偶尔会在图形显示中出现奇怪的行为。但是按照我编写的方式使用调度队列会导致实时字节爆炸,而如果我将这些行注释掉,则实时字节数会稳定下来。

我做错了什么?提前谢谢!

我在主线程中启动NSTimer:

 -(void) startGeoHardware
 {
     if (self.geoHardwareArrayTimer == nil)
     {

         self.geoHardwareArrayTimer = [NSTimer      scheduledTimerWithTimeInterval:arrayTimerUpdate
                                                                  target:self
                                                                selector:@selector(startGeoHardWareArray:)
                                                                userInfo:nil
                                                                 repeats:YES];

    }

 }

然后调用方法

 - (void) startGeoHardWareArray: (NSTimer *)geoHardwareArrayTimer  //: (CMCalibratedMagneticField)field
 {


     dispatch_queue_t runGeoHardwareArrayQueue = dispatch_queue_create("GeoHardwareArray",NULL);
     dispatch_async(runGeoHardwareArrayQueue, ^{

      //Do lots of stuff here

      //Finish lots of stuff here

     });
     dispatch_release(runGeoHardwareArrayQueue);

 }

geoHardwareArrayTimer在.h文件中定义为

 NSTimer *geoHardwareArrayTimer;
 }
 @property(nonatomic,retain) NSTimer *geoHardwareArrayTimer;

并在.m文件中合成。并被解除分配

     if (self.geoHardwareArrayTimer != nil)
     {
         [self.geoHardwareArrayTimer invalidate];
         self.geoHardwareArrayTimer = nil;
     }

     [super dealloc];

1 个答案:

答案 0 :(得分:0)

好吧,这不是一个非常好的答案 - 它1)有点工作,2)提出另一个类似的问题 - 现在泄漏来自哪里???

在搜索更多帖子时,我发现了调度计时器方法。这似乎对我想要的东西非常有效:在这个简单的例子中,我创建并运行两个定时器并在不同的队列上运行方法 - 并且实时字节很快就会或多或少地稳定下来,接近常量。但是,开头有一次性泄漏:

OS_dispatch_source libdispatch.dylib _os_object_alloc_realized

这对我来说毫无意义。

任何想法???感谢

- (void)viewDidLoad
{
    [self createDispatchTimers];
}

- (void)createDispatchTimers
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    dispatch_source_t geoHardwareArrayTimer = CreateDispatchTimer(arrayTimerUpdate * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / arrayTimerLeeway, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Repeating task
        [self startGeoHardWareArray:geoHardwareArrayTimer];


    });


    dispatch_source_t geoHardwareTimer = CreateDispatchTimer(timerUpdate * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / timerLeeway, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Repeating task
        [self runGeoHardware:geoHardwareTimer];

    });


}





dispatch_source_t CreateDispatchTimer(uint64_t interval,
                                      uint64_t leeway,
                                      dispatch_queue_t queue,
                                      dispatch_block_t block)
{
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
                                                     0, 0, queue);
    if (timer)
    {
        dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
        dispatch_source_set_event_handler(timer, block);
        dispatch_resume(timer);
    }
    return timer;

}

void RemoveDispatchSource(dispatch_source_t timer)
{
    dispatch_source_cancel(timer);
    dispatch_release(timer);
}








- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}




///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// Here are the dispatch queue Methods ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////

- (void) startGeoHardWareArray: (dispatch_source_t) geoHardwareArrayTimer
{
    dispatch_queue_t runGeoHardwareArrayQueue = dispatch_queue_create("GeoHardwareArray",0);
    dispatch_async(runGeoHardwareArrayQueue, ^{

        NSLog(@"Array Timer running");

    });
    dispatch_release(runGeoHardwareArrayQueue);
}


- (void) runGeoHardware: (dispatch_source_t) geoHardwareTimer
{
    dispatch_queue_t runGeoHardwareQueue = dispatch_queue_create("GeoHardware",0);
    dispatch_async(runGeoHardwareQueue, ^{

        NSLog(@"Hardware Timer running");

    });
    dispatch_release(runGeoHardwareQueue);
}