web-dev-qa-db-fra.com

Comment arrêter NSTimer

Hé, je fais juste un exemple d'application et j'ai quelques problèmes, j'ai donc une vue sous forme de tableau, puis quelques lignes et lorsqu'un utilisateur clique sur une ligne, il passe à une nouvelle vue. Sur cette vue, j'ai un bouton pour jouer de la musique. J'utilise une minuterie pour augmenter le curseur en fonction de la durée de la musique et du temps restant.

Maintenant, mon problème est: que dois-je mettre pour que lorsque je reviens à la vue tableau via le bouton en haut à gauche, le NSTimer s'arrête?

c'est ce que j'ai jusqu'à présent, je ne peux pas obtenir une répétition: OUI minuterie pour arrêter.

#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
32
cruisx

Utilisez le code ci-dessous. Cela fonctionnera Mais gardez à l'esprit qu'il ne doit être appelé que si notre minuterie est en mode en cours d'exécution, sinon l'application se plantera.

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

comme ça:

[yourtimername invalidate];

Mais attention, vous ne pouvez pas arrêter le chronomètre s'il est déjà arrêté car votre application va se bloquer.

13
DailyDoggy

Comme le dit iCoder, il doit être invalidé dans viewWillDisappear.

J'ai ajouté ce qui suit pour vous en assurer. ça marche pour moi. J'espère que ça aide (et ajoute à la réponse icoders ne pas l'intention de copier)

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

}
8
craigk

Poste de 4 ans, je sais mais je peux peut-être sauver le gars de NEXT de perdre du temps à essayer d’invalider un NSTimer. La documentation sur les pommes l'explique et cela fonctionne pour moi.

en .h

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

dans M

@synthesize yourTimer, repeatingTimer;

dans viewDidLoad

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

  self.repeatingTimer = yourTimer;

dans ma vueDidDisappear

   [repeatingTimer invalidate];
   repeatingTimer = nil;

l'astuce consiste à affecter le premier objet NSTimer à un objet (faible) NStimer et à tuer cet objet.

6
user1045302

Vous pouvez utiliser deux choses différentes

    [timername invalidate];

Ou vous pourriez utiliser

    timername = nil;
2
VortexGamez

L’astuce consiste à utiliser une classe singleton, la classe Google myGlobals qui est principalement utilisée en tant que singleton Bien que si vous souhaitez utiliser NSTimer, alors

disons que la vue 1 est celle dans laquelle vous allez et la vue 2 est celle dans laquelle vous revenez 2.

Donc, dans le cas de la vue 2, écrivez la NSTimer pour invalider le temporisateur dans la viewDidLoad (En supposant que vous ayez deux classes séparées pour les deux vues). Alors, créez une classe Singleton et enregistrez le pointeur NSTimer comme ceci

//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];

oh, et voici le code de classe myGlobals dont vous aurez besoin

//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
1
Izac Mac

Il suffit d'invalider le chronomètre

[timer invalidate];

0
Raza.najam