2014-02-06 3 views
1

Согласно the answer of this post, вы не должны сбросить dispatch_once_t isn't a good thing to do in any situation other than testing.Сброс dispatch_once_t?

Скажем, у меня есть раздел кода, который я хочу удостовериться, что он не может быть вызван несколькими потоками за один раз (например, загрузка данных). Это недействительный код:

@interface SomeClass() 
{ 
    dispatch_once_t onceToken; 
} 
@end 

- (void) updateMethod 
{ 
    dispatch_async(dispatch_get_global_queue(0, 0), ^{ 
     dispatch_once(&onceToken, ^{ 
      // Do some data loading in the background. 
      ... 

      dispatch_async(dispatch_get_main_queue(), ^{ 
       // Update the UI 
       ... 

       // Reset the once token. Allow the method to be called again. 
       onceToken = 0; 
      }); 
     }); 
    }); 
} 

Есть ли проблемы с этим кодом? Или это должно быть сделано другим путем?

+1

От http://stackoverflow.com/a/19845164/1187415: dispatch_once_t не должен быть переменной экземпляра. –

ответ

3

Для этого не следует использовать dispatch_once. Для этого типа задач вы должны использовать последовательную очередь или какую-то блокировку или семафор, в зависимости от ваших потребностей.

Для первого выбора вы можете выполнять загрузку фона параллельно, но очереди обновлений пользовательского интерфейса в основную очередь, которая является последовательной очередью, а обновления пользовательского интерфейса должны выполняться в основной очереди.

Если вам требуется, чтобы загрузка фона была последовательной, и вы ставите в очередь, что в последовательной очереди вы можете создать ее с помощью dispatch_queue_create().

Для второго выбора GCD предоставляет семафоры - dispatch_semaphore_create(), dispatch_semaphore_signal() и dispatch_semaphore_wait().

В общих чертах вы:

  1. Создать семафор с отсчетом 1.
  2. Если вы хотите запустить вы ждете от семафора, ваш поток блокируется, если семафор имеет значение 0, для > 0 счетчик уменьшается, а поток продолжает
  3. Когда работа будет сделано, вы сигнал семафора - что увеличивает его

HTH