2010-08-18 10 views
31

Hola, solo estoy haciendo una aplicación de ejemplo y estoy teniendo un pequeño problema, entonces tengo una vista de tabla y luego tengo unas pocas filas y cuando un usuario hace clic en una fila, las lleva a una nueva ver. En esta vista, tengo un botón para reproducir música. Estoy usando un temporizador para aumentar la barra deslizadora en función de la duración de la música y el tiempo restante.Cómo detener NSTimer

Ahora mi problema es, ¿qué tengo que poner para que cuando regrese a la vista de tabla mediante el botón superior izquierdo, se detenga el NSTimer?

esto es lo que tengo hasta ahora, no puedo obtener una repetición: SÍ temporizador para detener.

#import "SecondViewController.h" 

@implementation SecondViewController 
@synthesize lbl1; 
@synthesize timer; 

-(IBAction) slide { 
myMusic.currentTime = slider.value; 
} 

-(IBAction)play 
{ 
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES]; 
slider.maximumValue = [myMusic duration]; 
myMusic.volume = 0.2; 
[myMusic prepareToPlay]; 
[myMusic play]; 
} 

-(IBAction)pause 
{ 
[myMusic pause]; 
} 

-(IBAction)stop 
{ 
slider.value = 0; 
myMusic.currentTime = 0; 
[myMusic stop]; 
} 

- (void)updateTime{ 
    slider.value = myMusic.currentTime; 
} 

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 
- (void)viewDidLoad { 

    //This plays music, we must give it a path to find the file and then u can change it. 
NSString * pathToMusicFile = [[NSBundle mainBundle] pathForResource:@"Katy" ofType:@"mp3"]; 
    myMusic = [[ AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:pathToMusicFile] error:NULL]; 
    myMusic.delegate = self; 
    myMusic.numberOfLoops = -1; 

slider.value = 0; 
//[myMusic play]; 

    [super viewDidLoad]; 
} 


- (void)viewDidUnload { 

[timer invalidate]; 
timer = nil; 
//myMusic.currentTime = 0; 
[myMusic stop]; 
[super viewDidUnload]; 

// Release any retained subviews of the main view. 
// e.g. self.myOutlet = nil; 
} 

-(IBAction) TxtChange;{ 

lbl1.text = @" test2! I CHNAGED TEXT FROM ANOTHER XIB"; 
} 

- (void)dealloc { 
[timer invalidate]; 
timer = nil; 
[myMusic release]; 
    [super dealloc]; 
} 

@end 

Respuesta

13

así:

[yourtimername invalidate]; 

Pero tenga cuidado, No puedes detener el temporizador si ya está detenido debido a que su aplicación va a estrellarse.

+2

La aplicación no falla cuando invalido un temporizador no instanciado. – IgniteCoders

67

Utilice el siguiente código. Funcionará Pero tenga en cuenta que solo debe invocarse si nuestro temporizador está en modo de ejecución o la aplicación se bloqueará.

- (void)viewWillDisappear:(BOOL)animated { 
    //BEFORE DOING SO CHECK THAT TIMER MUST NOT BE ALREADY INVALIDATED 
    //Always nil your timer after invalidating so that 
    //it does not cause crash due to duplicate invalidate 
     if(timer) 
     { 
     [timer invalidate]; 
     timer = nil; 
     } 
    [super viewWillDisappear:animated]; 
} 
+0

Voy a probar esto en la mañana, son las 2 AM, me he quedado atrapado en esto todo el día. Espero que tu solución funcione. volveré a esta publicación en unas pocas horas. – cruisx

+21

alguien debería decirle que tiene 3 años de retraso en ese todo volviendo a lo suyo ... ¡De cualquier forma, solucionó mi problema! –

+0

@JonMattingly lol –

8

Como iCoder dice que tiene que ser invalidado en viewWillDisappear.

Agregué lo siguiente solo para estar seguro. esto funciona para mi. Creo que sirve (y se suma a icoders respuesta no tiene intención de copiar)

- (void) startTimer 
{ 
[self stopTimer]; 
timer = [NSTimer scheduledTimerWithTimeInterval: 5.0 
                target: self 
                selector:@selector(onTick) 
                userInfo: nil repeats:YES]; 

} 

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

} 
1

truco es usar una clase Singleton, Google myGlobals clase que se utiliza sobre todo como un conjunto unitario Aunque u si deseamos usar NSTimer y, a continuación

digamos la vista 1 es la que u ir en vista y 2 es el que u ir hacia atrás 2.

Así que en caso de visión 2, se el NSTimer para invalidar el temporizador en el viewDidLoad (Suponiendo que tiene dos clases separadas para ambas vistas s). Se producirá un problema porque cuando vaya a ver 1, la vista 2 temporizadores será dealloc. Por lo tanto, hacer una clase Singleton y guardar el puntero NSTimer como esto

//to be done in viewDidLoad function 
theGlobals *globals = [theGlobals alloc] init];// for the singleton class to initiate, 
[globals.myTimer invalidate]; 


//to be done in viewDidUnload 
theGlobals *globals = [theGlobals alloc] init];// for the singleton class to initiate, 
globals.myTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 
               target: self 
               selector:@selector(onTick) 
               userInfo: nil repeats:YES]; 

Ah, y aquí está el código de clase myGlobals que u necesitará

//theglobals.h file 

#import <Foundation/Foundation.h> 


@interface theGlobals : NSObject 
{ 
    NSTimer *myTimer; 
} 

@property (nonatomic, copy) NSString *changeyes; 



+(theGlobals*)sharedInstance; 
@end 

//implementaton .m file 

#import "theGlobals.h" 
@implementation theGlobals 

@synthesize myTimer; 



static theGlobals *sharedInstance; 

- (id) init 
{ 
return self; 
} 

+(theGlobals*)sharedInstance 
{ 
if (!sharedInstance) 
{ 
    sharedInstance = [[theGlobals alloc] init]; 
} 
return sharedInstance; 
} 
@end 
2

se pueden utilizar dos cosas diferentes

[timername invalidate]; 

o puede utilizar

timername = nil; 
+0

Este último no detendrá el cronómetro, y el primero ya se publicó en agosto de 2010. –

6

Publicación de 4 años, lo sé, pero quizás pueda salvar al chico NEXT de perder tiempo intentando invalidar un NSTimer. La documentación de las manzanas lo explica y funciona para mí.

en .h

@property(nonatomic, retain) NSTimer *yourTimer; 
@property(weak) NSTimer *repeatingTimer; 

en.m

@synthesize yourTimer, repeatingTimer; 

en viewDidLoad

yourTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimerInterval)(40.0/60.0) 
              target:self 
              selector:@selector(blink) 
              userInfo:nil 
              repeats:TRUE]; 

    self.repeatingTimer = yourTimer; 

en mi viewDidDisappear

[repeatingTimer invalidate]; 
    repeatingTimer = nil; 

el truco consiste en la asignación de la primera NSTimer a (débil) NSTimer objeto y matar a ese objeto.

0

Sólo invalidar el temporizador

[invalidate temporizador];