Reputation: 285
I use this code for stopping NSTimer
[timer invalidate]
timer = nil;
It works fine for the first run. But, after I resume the timer with this code.
timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(checkNewUpdates)
userInfo:nil
repeats:YES];
NSTimer
won't stop anymore with [timer invalidate]
Upvotes: 0
Views: 241
Reputation: 11939
It look like multiple instance of timer is running simultaneously. You can do one thing, before start to run a new timer, check for previous instance of timer, and if timer instance is available, then invalidate it. After this start new instance
if(timer)
{
[timer invalidate];
timer = nil;
}
timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(checkNewUpdates)
userInfo:nil
repeats:YES];
Upvotes: 3
Reputation: 1840
I know this doesnt answer your question per-se;
Can I suggest using polling mechanism instead of a timer? Ive had a world of trouble with NSTimers
in the past and polling was a good alternative. Ive made a simple one below.
- (void) doPoll {
// do logic here
if (shoudStop) {
return;
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, X * NSEC_PER_SEC)),
dispatch_get_main_queue(), ^{
[self doPoll];
});
}
This is just a simple example, it does not stop retain cycles
If you choose to try this, Yours should.
Hope it helps.
Upvotes: 0
Reputation: 13619
Just invalidate the timer inside the selector that fires. That will ensure you have a pointer to the correct timer (which is probably why your invalidate
call isn't working:
timer = [NSTimer scheduledTimerWithTimeInterval:5.0
target:self
selector:@selector(checkNewUpdates:)
userInfo:nil
repeats:YES];
Note the colon after checkNewUpdates:
Then, in your checkNewUpdates: method, do something like this:
- (void)checkNewUpdates:(NSTimer*)timer
{
// do somehting
// Then, check if the criteria for stopping the timer has been met, and invalidate it here.
if( self.shouldStopTimer ) // made up variable, use your own criteria.
{
[timer invalidate];
}
}
Upvotes: 0
Reputation: 11197
In apple's official document they said:
You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
If your timer is running on main thread, do this:
[timer performSelectorOnMainThread:@selector(invalidate) withObject:nil waitUntilDone:YES];
If it is on any other thread, lets call the thread myThread, then do this:
[timer performSelector:@selector(invalidate) onThread:myThread withObject:nil waitUntilDone:NO];
Hope this helps.. :)
Upvotes: 1