Инвалидность 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);
Другие вопросы по тегам