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
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];
}
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.
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;
}
}
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.
Vous pouvez utiliser deux choses différentes
[timername invalidate];
Ou vous pourriez utiliser
timername = nil;
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
Il suffit d'invalider le chronomètre
[timer invalidate];