NSTimer не останавливается

У меня есть таймер, который срабатывает, когда метод viewWillAppear вызывается и недействителен при вызове метода viewDidDisappear. Но после определенного переключения между видами таймер продолжает стрелять даже после того, как он был признан недействительным. В чем проблема?

Вот мой код:

NSTimer *timer;

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f
                     target: self
                     selector:@selector( timerAction )
                     userInfo:nil
                     repeats:YES];
}

-(void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [timer invalidate];
    timer = nil;
}

-(void) timerAction
{
    NSLog(@"timerAction");
}

Ответ 1

Я должен был держать ссылку на таймер, сохраняя его.:) Я задал этот вопрос 5 месяцев назад, и это потрясающе, насколько больше опыта я приобрел.:)

timer = [ [NSTimer scheduledTimerWithTimeInterval: ...] retain];
...
...
[timer invalidate];
[timer release];

Ответ 2

Это абсолютное решение. Ни один из вышеперечисленных не работал у меня, поэтому я сделал это,

где вы хотите запустить таймер,

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];

Метод, который вызывает таймер,

-(void)timerMethod
{
    // do what you need to do

    if (needs to be called again) {

        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:NO];        
    }
}

надеюсь, что это поможет,

Ответ 3

Метод, вызываемый таймером, должен иметь определение

- (void)methodName:(NSTimer *)aTimer;

Таким образом, метод имеет экземпляр таймера, который был запущен. То, как вы это делаете, метод не будет знать, был ли таймер недействительным или нет.

Попробуйте изменить инициализацию таймера на

timer = [NSTimer scheduledTimerWithTimeInterval: 0.2f target: self selector:@selector(timerAction:) userInfo:nil repeats:YES]

и метод

-(void) timerAction:(NSTimer *)aTimer{...}

Надеюсь, что поможет

Ответ 4

Это может быть и не проблема, но вам нужно сохранить ссылку на таймер, который возвращается из schedTimerWithInterval:. Без этого указатель на таймер может оказаться недействительным к моменту его остановки.

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    timer = [[NSTimer scheduledTimerWithTimeInterval:0.2f target:self selector:@selector(timerAction) userInfo:nil repeats:YES] retain];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [timer invalidate];
    [timer release];
    timer = nil;
    [super viewDidDisappear:animated];
}

- (void)dealloc
{
    [timer invalidate];
    [timer release];
    timer = nil;
    [super dealloc];
}

Также попробуйте установить точку останова в viewDidDisappear и убедитесь, что она вызвана!

Ответ 5

**In .h class**

@interface 
{
NSTimer * theTimer;

}


**in .m class**

//put this code where you want to calling the NSTimer function

        theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateCounter:) userInfo:nil repeats:YES];



- (void)updateCounter:(NSTimer *)theTimer 
{

   // write your code here for counter update 

}


// put this code to Stop timer:

    [theTimer invalidate];
    theTimer = nil;

Ответ 6

Это помогло мне в Swift

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)

    dispatch_async(dispatch_get_main_queue(),{ [weak self] in

        self?.idleTimer?.invalidate()
        self?.idleTimer = nil

    })

}

Ответ 7

Вы забыли снять таймер в viewWillDisappear:

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [timer invalidate];
    [timer release];
    timer = nil;
}

Это не должно заставлять таймер продолжать стрельбу, хотя...

Ответ 8

invalidate doco говорит

"Цикл запуска удаляет и освобождает таймер, либо перед тем как метод invalidate вернется, либо в какой-то более поздний момент."

Я предполагаю, что ваш будет удален в какой-то более поздний момент.

Ответ 9

У меня была та же проблема.

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

- (void)stopTimer
{
    [timer invalidate];
    [timer release];
    timer = nil;
}

После вызова этого метода мой таймер действительно остановится

Ответ 10

- (void)viewWillAppear:(BOOL)animated снова вызывается.

Фактически он вызывается каждый раз при переключении просмотров или после отклонения модального представления. В принципе, каждый раз, когда ваше представление действительно появляется на экране, а не только в первый раз.

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

Ответ 11

После создания вашего таймера просто зарегистрируйте его для запуска в NSRunLoopCommonModes:

[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];

Тогда метод invalidate будет работать.

Ответ 12

Это работает для меня

dispatch_async(dispatch_get_main_queue(), ^{
    [timer invalidate];
});