Почему текущие байты продолжают расти при запуске цикла NSTimer из основной очереди?

#ios #multithreading #nstimer #dispatch

#iOS #многопоточность #nstimer #отправка

Вопрос:

Я искал похожие темы в 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:

Хорошо, это не совсем хороший ответ — он 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);
}