Инвалидность NSTimer из его метода вызова
Я запланировал таймер с помощью [NSTimer scheduleTimerWithTimeInterval:target:selector:userInfo:] и хочу сделать его недействительным в какой-то момент, когда он срабатывает.
- (id)init
{
[NSTimer scheduledTimerWithInterval:1 target:self selector:@selector(fired:) userInfo:nil repeats:YES];
}
- (void)fired:(NSTimer *)timer
{
if (someCondition) {
[timer invalidate];
}
}
Это разрешено? Документация гласит
Вы должны отправить это сообщение из потока, в котором был установлен таймер. Если вы отправите это сообщение из другого потока, источник ввода, связанный с таймером, может не быть удален из цикла его выполнения, что может помешать правильному выходу из потока.
Если это не правильный способ выполнить эту задачу: каков правильный путь?
2 ответа
Это нормально, чтобы сделать его недействительным из запущенного метода, так как запущенный метод находится в том же потоке, на который был запланирован таймер:
scheduledTimerWithTimeInterval: мишень: селектор: UserInfo: повторы:
Создает и возвращает новый объект NSTimer и планирует его в текущем цикле выполнения в режиме по умолчанию.
Призвание [timer invalidate]
изнутри метода fire просто отлично, этот код будет выполняться в том же потоке, что и тот, который использовался при создании таймера.
Указанный вами Apple Doc предупреждает вас, что если вы создадите отдельный поток и лишите его таймера, то, и только тогда, следует ожидать непредсказуемого поведения.
Ex.
// Create the background queue
dispatch_queue_t queue = dispatch_queue_create("do not do this", NULL);
// Start work in new thread
dispatch_async(queue, ^ {
// !! do not do this !!
if (someCondition) {
[yourTimer invalidate];
}
// or this
[self fire:yourTimer];
});
// won’t actually go away until queue is empty
dispatch_release(queue);