2010-08-18 10 views
31

Hej, więc właśnie robię przykładową aplikację i mam trochę problemów, więc mam widok tabeli, a następnie mam kilka wierszy, a gdy użytkownik kliknie wiersz, zabiera je do nowego widok. W tym widoku mam przycisk do odtwarzania muzyki. Używam timera, aby zwiększyć suwak na podstawie czasu trwania muzyki i pozostałego czasu.Jak zatrzymać NSTimer

Teraz mój problem polega na tym, co muszę umieścić, aby po przejściu do widoku tabeli lewym górnym przyciskiem wyłączyć NSTimer?

To jest to, co mam do tej pory, nie mogę uzyskać powtórzyć: TAK timer, aby zatrzymać.

#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 

Odpowiedz

13

tak:

[yourtimername invalidate]; 

Ale uważaj, nie można zatrzymać stoper, gdy jest on już zatrzymany, ponieważ aplikacja padnie.

+2

Aplikacja nie zawiesza się, gdy unieważniam timer nie utworzony. – IgniteCoders

67

Użyj poniższego kodu. Będzie działać Należy jednak pamiętać, że musi on zostać wywołany tylko wtedy, gdy nasz licznik jest uruchomiony, w przeciwnym razie aplikacja ulegnie awarii.

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

Mam zamiar spróbować tego rano, o 2 nad ranem, utknąłem na tym cały dzień. Mam nadzieję, że twoje rozwiązanie działa. źle wrócę do tego postu za kilka godzin. – cruisx

+21

ktoś powinien mu powiedzieć, że spóźnił się o 3 lata na to, że wrócił do ciebie ... Tak czy inaczej, poprawił mój problem! –

+0

@ JonMattingly lol –

8

Jak twierdzi iCoder, musi zostać unieważniony w viewWillDisappear.

Dodałem tylko po to, aby się upewnić. mi to pasuje. Nadzieję, że to pomaga (i dodaje do icoders odpowiedź nie zamiar kopia)

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

Sztuką jest, aby użyć klasy singleton, myGlobals google klasa który jest stosowany głównie jako pojedyncza Chociaż jeśli u chcą używać NSTimer , następnie

powiedzmy widok 1 jest u których wchodzić i widok 2 jest ten, który u wrócić 2.

Tak więc w przypadku widoku 2, napisać NSTimer unieważnić timer w viewDidLoad (Zakładając, że masz dwie oddzielne klasy dla obu widoków s) .Problem wystąpi, ponieważ po przejściu do widoku 1, zegary widoku 2 będą dealloc. Więc dokonać klasy Singleton i zapisać wskaźnik NSTimer jak ten

//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, a tu jest kod klasy myGlobals że u będzie musiał

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

można użyć dwie różne rzeczy

[timername invalidate]; 

Lub możesz użyć

timername = nil; 
+0

Ten ostatni właściwie nie zatrzyma stopera, a pierwszy został już wysłany w sierpniu 2010. –

6

4-letni post, wiem, ale może mogę uratować NEXT facet od marnowania czasu próbując unieważnić NSTimer. Dokumentacja jabłek wyjaśnia to i działa dla mnie.

w .h

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

w.m

@synthesize yourTimer, repeatingTimer; 

w viewDidLoad

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

    self.repeatingTimer = yourTimer; 

moim viewDidDisappear

[repeatingTimer invalidate]; 
    repeatingTimer = nil; 

trick jest przypisanie pierwszej NSTimer do (słabe) obiektu NStimer i zabijania przedmiotu.

0

Wystarczy unieważnić timer

[czasomierz invalidate];