Как остановить NSTimer - PullRequest
       15

Как остановить NSTimer

32 голосов
/ 18 августа 2010

Эй, я просто делаю пример приложения, и у меня возникли небольшие проблемы. Итак, у меня есть табличное представление, а затем у меня есть несколько строк, и когда пользователь щелкает строку, он переносит их в новое представление. На этом экране у меня есть кнопка для воспроизведения музыки. Я использую таймер, чтобы увеличить ползунок в зависимости от продолжительности музыки и оставшегося времени.

Теперь моя проблема в том, что я должен поставить, чтобы, когда я возвращаюсь к табличному виду через верхнюю левую кнопку, NSTimer останавливается?

это то, что у меня есть, я не могу повторить: ДА, таймер остановится.

#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

Ответы [ 7 ]

67 голосов
/ 18 августа 2010

Используйте приведенный ниже код.Это будет работать, но имейте в виду, что он должен вызываться только в том случае, если наш таймер находится в рабочем режиме, иначе приложение будет аварийно завершено.

- (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];
}
13 голосов
/ 18 августа 2010

как это:

[yourtimername invalidate];

Но будьте осторожны, вы не можете остановить таймер, если он уже остановлен, потому что ваше приложение вылетит.

8 голосов
/ 02 июня 2011

Как говорит iCoder, его нужно сделать недействительным в viewWillDisappear.

Я добавил следующее, чтобы убедиться. меня устраивает. Надеюсь, что это поможет (и добавляет к icoders ответ не намерены копировать)

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

}
6 голосов
/ 01 мая 2015

4-летний пост, я знаю, но, возможно, я могу спасти СЛЕДУЮЩЕГО парня от потери времени, пытаясь лишить законной силы NSTimer. Документация Apple объясняет это, и это работает для меня.

в .ч

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

дюйм. М

@synthesize yourTimer, repeatingTimer;

в viewDidLoad

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

  self.repeatingTimer = yourTimer;

на мой взглядDidDisappear

   [repeatingTimer invalidate];
   repeatingTimer = nil;

Хитрость в том, чтобы назначить первый NSTimer (слабому) объекту NStimer и убить объект THAT.

2 голосов
/ 09 июня 2014

Вы можете использовать две разные вещи

    [timername invalidate];

Или вы можете использовать

    timername = nil;
1 голос
/ 07 марта 2012

Хитрость заключается в использовании одноэлементного класса, класса google myGlobals, который в основном используется как одноэлементный. Хотя если вы действительно хотите использовать NSTimer, то

позволяет сказать, что представление 1 - это то, в которое вы переходите ипредставление 2 - это то, что вы вернетесь назад 2.

Так что в случае представления 2 напишите NSTimer, чтобы сделать недействительным таймер в viewDidLoad (при условии, что у вас есть два отдельных класса для обоих представлений).Проблема возникнет, потому что когда вы перейдете к просмотру 1, таймеры представления 2 будут освобождены.Итак, создайте класс Singleton и сохраните указатель NSTimer следующим образом

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

о, и вот код класса myGlobals, который вам понадобится

//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
0 голосов
/ 19 июля 2017

Просто аннулировать таймер

[таймер аннулировать];

...