2010-08-18 20 views
31

Hey, ich mache nur eine Beispielanwendung und ich habe ein kleines Problem, also habe ich eine Tabellenansicht und dann habe ich ein paar Zeilen und wenn ein Benutzer eine Zeile klickt, nimmt sie sie zu einem neuen Aussicht. Auf dieser Ansicht habe ich einen Knopf, um Musik zu spielen. Ich verwende einen Timer, um einen Schieberegler basierend auf der Musikdauer und der verbleibenden Zeit zu erhöhen.So stoppen Sie NSTimer

Jetzt ist mein Problem, was muss ich setzen, damit, wenn ich zurück zur Tabellenansicht über den oberen linken Knopf gehe, dass der NSTimer stoppt?

das ist was ich bisher habe, kann ich nicht wiederholen: YES Timer zu stoppen.

#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 

Antwort

13

wie folgt aus:

[yourtimername invalidate]; 

Aber Vorsicht, man kann den Timer stoppen, wenn es bereits gestoppt, weil die App abstürzt.

+2

Die App stürzt nicht ab, wenn ich einen nicht instanziierten Timer ungültig mache. – IgniteCoders

67

Verwenden Sie den folgenden Code. Es wird funktionieren Aber bedenken Sie, dass es nur aufgerufen werden muss, wenn unser Timer im laufenden Modus ist, sonst wird die Anwendung abgestürzt.

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

Ich werde gehen, versuchen Sie es am Morgen, es ist 2 Uhr morgens, stecken den ganzen Tag fest. Hoffentlich funktioniert deine Lösung. Ich komme in ein paar Stunden zurück zu diesem Post. – cruisx

+21

jemand sollte ihm sagen, er ist etwa 3 Jahre zu spät in diesem ganzen zurück zu dir Ding ... Auf jeden Fall, behoben mein Problem! –

+0

@ JonMattingly lol –

8

Wie iCoder sagt, muss es in ViewWillDisappear ungültig gemacht werden.

Ich habe die folgenden nur hinzugefügt, um sicherzustellen, dass. Für mich geht das. Hoffe, es hilft (und fügt Antwort auf icoders nicht Absicht zu kopieren)

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

Trick ist es, eine Singleton-Klasse zu verwenden, die google myGlobals Klasse meist als Singleton verwendet wird Obwohl, wenn u NSTimer wollen verwenden

, dann

sagen lässt die Ansicht 1 ist, die u gehen und Ausblick 2 ist derjenige, der u zurückgehen 2.

Also bei view 2, schreiben die NSTimer den Timer in der viewDidLoad ungültig zu machen (Angenommen, Sie haben zwei separate Klassen für beide Ansichten s) .Problem wird auftreten, weil, wenn Sie zur Ansicht 1 gehen, die Ansicht 2 Timer dealloc werden. Also, eine Singleton-Klasse machen und speichern Sie die NSTimer Zeiger wie diese

//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, und hier ist die myGlobals Klasse Code, der u

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

benötigen Sie zwei verwenden könnte verschiedene Dinge

[timername invalidate]; 

oder Sie können verwenden

timername = nil; 
+0

Letzterer stoppt den Timer nicht wirklich und der erste wurde bereits im August 2010 gepostet. –

6

4 Jahre alter Beitrag, ich weiß, aber vielleicht kann ich den nächsten Kerl vor der Zeitverschwendung retten, indem ich einen NSTimer ungültig mache. Apples Dokumentation erklärt es und es funktioniert für mich.

in .h

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

in.m

@synthesize yourTimer, repeatingTimer; 

in viewDidLoad

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

    self.repeatingTimer = yourTimer; 

in meinem viewDidDisappear

[repeatingTimer invalidate]; 
    repeatingTimer = nil; 

Der Trick ist bei der Zuordnung des ersten NSTimer bis (schwach) NSTimer Gegenstand und tötet das Objekt.

0

Nur den Timer ungültig machen

[timer invalidate];