NSTimer não para

Eu tenho um timer que é acionado quando o método viewWillAppear está sendo chamado e invalida quando o método viewDidDisappear está sendo chamado. Mas depois de uma certa quantidade de alternância entre as visualizações, o timer continua triggersndo mesmo depois de ter sido invalidado. Qual é o problema?

Aqui está o meu 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"); } 

    Eu deveria ter mantido um link para o timer, mantendo-o. 🙂 Eu fiz esta pergunta há 5 meses, e é incrível, quanto mais experiência eu adquiri. 🙂

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

    Esta é uma solução absoluta. Nenhum dos acima funcionou para mim, então eu fiz isso,

    onde você quer iniciar o timer,

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

    O método que o timer chama

     -(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 isto ajude,

    Um método chamado por um timer deve ter a definição

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

    Desta forma, o método tem a instância do timer que foi triggersda. Do jeito que você está fazendo, o método não saberá se o cronômetro foi invalidado ou não.

    Tente alterar a boot do timer para

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

    e o método para

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

    espero que ajude

    Esse pode não ser o problema, mas você precisa manter a referência ao timer retornado de scheduledTimerWithInterval :. Sem fazer isso, seu ponteiro para o cronômetro pode ser inválido no momento em que você for interrompê-lo.

     - (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]; } 

    Além disso, tente definir um ponto de interrupção no viewDidDisappear e verifique se ele está sendo chamado!

     **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; 

    Isso fez o truque para mim em Swift

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

    Você esqueceu de liberar o timer na viewWillDisappear:

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

    Isso não deve fazer com que o timer continue triggersndo …

    De invalidate o doco diz

    “O loop de execução remove e libera o timer, seja antes do retorno do método de invalidação ou em algum momento posterior.”

    Eu suponho que o seu está sendo removido em algum momento posterior.

    Eu tive o mesmo problema.

    Não consigo desalocar minha instância se o timer ainda estiver em execução, por isso preciso pará-lo antes de chamar:

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

    Depois de chamar esse método, meu timer realmente pára

    - (void)viewWillAppear:(BOOL)animated é chamada novamente.

    Na verdade, ele é chamado toda vez que você alterna as visualizações ou depois que você descarta uma exibição restrita. Basicamente, a qualquer momento, sua exibição reaparecerá na canvas, não apenas na primeira vez.

    Portanto, neste caso, o timer é reiniciado, mesmo que tenha sido invalidado antes.

    Depois de criar seu timer, registre-o para executar em NSRunLoopCommonModes :

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

    Em seguida, o método invalidate funcionará.

    Isso funciona para mim

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