NSTimer no se detiene

Tengo un temporizador que se dispara cuando se viewWillAppear método viewWillAppear e invalida cuando se viewDidDisappear método viewDidDisappear . Pero después de una cierta cantidad de cambio entre las vistas, el temporizador continúa disparando incluso después de que se haya invalidado. ¿Cuál es el problema?

Aquí está mi código:

 NSTimer *timer; - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f target: self selector:@selector( timerAction ) userInfo:nil repeats:YES]; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [timer invalidate]; timer = nil; } -(void) timerAction { NSLog(@"timerAction"); } 

Debería haber estado manteniendo un enlace al temporizador reteniéndolo. 🙂 Hace 5 meses hice esta pregunta, y es increíble, cuánta más experiencia adquirí. 🙂

 timer = [ [NSTimer scheduledTimerWithTimeInterval: ...] retain]; ... ... [timer invalidate]; [timer release]; 

Esta es una solución absoluta. Ninguno de los anteriores funcionó para mí, así que hice esto,

donde quieres iniciar el temporizador,

 [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO]; 

El método que el temporizador llama

 -(void)timerMethod { // do what you need to do if (needs to be called again) { [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO]; } } 

espero que esto ayude,

Un método llamado por un temporizador debe tener la definición

 - (void)methodName:(NSTimer *)aTimer; 

De esta forma, el método tiene la instancia del temporizador que se activó. La forma en que lo está haciendo, el método no sabrá si el temporizador fue invalidado o no.

Intente cambiar la inicialización de su temporizador

 timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f target: self selector:@selector(timerAction:) userInfo:nil repeats:YES] 

y el método para

 -(void) timerAction:(NSTimer *)aTimer{...} 

Espero que ayude

Puede que esto no sea el problema, pero debe conservar la referencia al temporizador que se devuelve desde scheduledTimerWithInterval :. Sin hacer esto, su puntero al temporizador podría no ser válido cuando vaya a detenerlo.

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; timer = [[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(timerAction) userInfo:nil repeats:YES] retain]; } - (void)viewDidDisappear:(BOOL)animated { [timer invalidate]; [timer release]; timer = nil; [super viewDidDisappear:animated]; } - (void)dealloc { [timer invalidate]; [timer release]; timer = nil; [super dealloc]; } 

Además, intente establecer un punto de interrupción en viewDidDisappear y asegúrese de que se llame.

 **In .h class** @interface { NSTimer * theTimer; } **in .m class** //put this code where you want to calling the NSTimer function theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES]; - (void)updateCounter:(NSTimer *)theTimer { // write your code here for counter update } // put this code to Stop timer: [theTimer invalidate]; theTimer = nil; 

Esto me gustó en Swift

 override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) dispatch_async(dispatch_get_main_queue(),{ [weak self] in self?.idleTimer?.invalidate() self?.idleTimer = nil }) } 

Se olvidó de liberar el temporizador a la viewWillDisappear: de viewWillDisappear:

 - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [timer invalidate]; [timer release]; timer = nil; } 

Esto no debería hacer que el temporizador siga disparando …

De invalidate el doco dice

“El ciclo de ejecución elimina y libera el temporizador, ya sea justo antes de que regrese el método de invalidación o en algún momento posterior”.

Supongo que la tuya será eliminada en algún momento posterior.

Yo tuve el mismo problema.

No puedo desasignar mi instancia si el temporizador aún se está ejecutando, así que tengo que detenerlo antes de llamar:

 - (void)stopTimer { [timer invalidate]; [timer release]; timer = nil; } 

Después de llamar a este método, mi temporizador realmente se detiene

- (void)viewWillAppear:(BOOL)animated se llama de nuevo.

De hecho, recibe un llamado cada vez que se cambian las vistas o después de descartar una vista modal. Básicamente cada vez que su vista reaparece en la pantalla, no solo la primera vez.

Entonces, en este caso, el temporizador se reinicia, aunque ya se haya invalidado antes.

Después de crear su temporizador, solo regístrelo para ejecutar en NSRunLoopCommonModes :

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];

Entonces el método de invalidate funcionará.

Esto funciona para mí

 dispatch_async(dispatch_get_main_queue(), ^{ [timer invalidate]; });