#ios #objective-c-blocks #grand-central-dispatch
#iOS #objective-c-блоки #grand-central-отправка
Вопрос:
Я выполняю поток, который продолжает искать обновления с веб-сайта. Должна быть возможность установить частоту обновления в некотором представлении.
Поток обновления продолжает проверять наличие обновленного интервала. Но я хотел бы избежать условий гонки. (Должен ли я вообще беспокоиться об этом с помощью GCD?)
//This variable is used to avoid race conditions, refreshRate is a instance variable
int threadRefreshRate = refreshRate;
BOOL autoRefresh = YES;
dispatch_async(autoUpdateQueue, ^ {
while(YES){
NSLog(@"Runs autoupdate thread");
dispatch_async(dispatch_get_main_queue(), ^{
if(autoRefresh){
[self checkForUpdate];
//Trying to set thread variable to avoid race condition
threadRefreshRate = refreshRate;
}
else
NSLog(@"Should not auto refresh");
});
sleep(threadRefreshRate);
}
});
Я попытался реализовать этот код. Однако это не работает для определения переменной ‘thread’ внутри блока.
Ответ №1:
Для кода, который вы указали, я бы использовал события таймера, возникающие в очереди, вместо того, чтобы выполнять явный переход в режим ожидания в коде. Таким образом, вам не придется беспокоиться об условиях гонки и т.д..
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
if (!timer) return;
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), refreshRate * NSEC_PER_SEC, 5 * NSEC_PER_SEC);
dispatch_source_t timer = self.timer;
//initialize self to blockSelf with __block
self.timerAction = ^{
[blockSelf checkForUpdate];
};
dispatch_source_set_event_handler(timer, timerAction);
dispatch_resume(timer);
Когда для автоматического обновления установлено значение NO, вы можете отменить его с помощью
dispatch_source_cancel(timer);
Комментарии:
1. Значит, мне вообще не нужно запускать цикл a? Нужно ли мне использовать глобальную очередь?
2. @Johan Да, вам не обязательно запускать цикл. Я думаю, что события таймера также могут быть вызваны в других очередях.