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];
});