Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I invalidate timer when I don't create NSTimer object

Tags:

ios

nstimer

I don't want to create NSTimer object. How do I invalidate timer? I want to invalidate timer in viewWillDisappear.

-(void) viewDidLoad
{ 
 [super viewDidLoad];
 [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}
like image 319
Voloda2 Avatar asked Aug 30 '12 07:08

Voloda2


2 Answers

A

you have to hold on to the timer you create:

@interface MONObject ()
@property (nonatomic, retain) NSTimer * timerIvar;
@end

@implementation MONObject
...
- (void)viewDidLoad
{ 
 [super viewDidLoad];
 self.timerIvar = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(onTimer:) userInfo:nil repeats:YES];
}

- (void)invalidateTimer
{
  [self.timerIvar invalidate];
  self.timerIvar = nil;
}

- (void)viewWillDisappear:(BOOL)animated
{
  ...
  [self invalidateTimer];
}

B

another option would be to invalidate the timer that is passed in the callback, but that won't occur within viewDidUnload:. therefore, it doesn't quite apply in this scenario:

- (void)onTimer:(NSTimer *)pTimer
{
  [pTimer invalidate];
}
like image 161
justin Avatar answered Oct 21 '22 08:10

justin


If you want to be able to cancel the timer, you have to refer to the timer you’re cancelling, and that means you have to keep the pointer to the timer around, see justin’s answer.

Keeping a reference to the timer is the right way to do it, but for the sake of completeness you may also use the -performSelector:withObject:afterDelay: method as a poor man’s timer. That call may be invalidated using +cancelPreviousPerformRequestsWithTarget:. Sample code:

- (void) viewDidLoad
{
    [super viewDidLoad];
    [self performSelector:@selector(timerTick) withObject:nil afterDelay:10];
}

And then:

- (void) viewWillDisappear
{
    [NSObject cancelPreviousPerformRequestsWithTarget:self];
    [super viewWillDisappear];
}

But this is not the right way to do it, because there might be other perform-selector requests pending on your object that you would cancel. It’s best to keep your timer around, that way you know exactly what you’re cancelling.

By the way, it’s also probably a bad idea to run a timer in -viewDidLoad. View loading may happen anytime, without any relation to view being displayed.

like image 32
zoul Avatar answered Oct 21 '22 08:10

zoul