NSTimer не останавливается с признаком недействительности

Я добавляю такой таймер

tim=[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(repeatTim) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:tim forMode:NSDefaultRunLoopMode];

tim это свойство NSTimer моего класса.

Затем я останавливаю его при нажатии кнопки

[[fbt tim] invalidate];
[fbt setTim:nil];

fbt это экземпляр моего класса.

если я вызываю только invalidate, тогда он не останавливается, но если я установил его в nil, тогда я получил EXC_BREAKPOINT

здесь код метода repeatTim в селекторе

AppDelegate *appDelegate = [[UIApplication sharedApplication]delegate];
[appDelegate.wbv stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"intal()"]];

Я попытался вызвать init и invalidate в

dispatch_async(dispatch_get_main_queue(), ^{})

он также не останавливает таймер.

Ответ 1

Прочитайте документацию для NSTimer:

Существует три способа создания таймера:

  • Используйте метод scheduleTimerWithTimeInterval: invocation: repeat: или scheduleTimerWithTimeInterval: target: selector: userInfo: repeat: class для создания таймера и планирования его в текущем цикле выполнения в режиме по умолчанию.

  • Используйте timerWithTimeInterval: invocation: repeat: или timerWithTimeInterval: target: selector: userInfo: repeat: метод класса для создания объекта таймера без его планирования в цикле выполнения. (После его создания вы должны добавить таймер в цикл выполнения вручную, вызвав метод addTimer: forMode: соответствующий объект NSRunLoop.)

  • Выделите таймер и инициализируйте его с помощью initWithFireDate: interval: target: selector: userInfo: repeat: method. (После его создания вы должны добавить таймер в цикл выполнения вручную, вызвав метод addTimer: forMode: соответствующий объект NSRunLoop.)

Вы используете метод, который уже добавляет его в mainLoop из 1. - вам нужно удалить эту строку или создать таймер с 2. подход и оставить ручное добавление.

Также помните, что вы должны отправить недействительное сообщение из потока, на котором был установлен таймер. Если вы отправляете это сообщение из другого потока, источник входного сигнала, связанный с таймером, не может быть удален из цикла запуска, что может помешать корректному выводу потока.

Ответ 2

У вас работает более одного таймера. Попробуйте следующее:

-(void)startTimer{
    [self.myTimer invalidate]; // kill old timer
    self.myTimer = [NSTimer scheduledTimerWithTimeInterval:0.2 target:self selector:@selector(doSomething) userInfo:nil repeats:YES];
}

-(void)stopTimer{
    [self.myTimer invalidate];  
    self.myTimer=nil; //set pointer to nil 
}