I'm setting a timer to fire a method after 30 sec if a specific condition is not met else/otherwise the timer would be invalidated. Here's is what i am doing I am creating a timer property like this
@property (nonatomic) NSTimer *timer;
Now in some method i am starting my timer like this
- (void) createAPIXML
{
if (_isGenerateRootTag) {
_root = (DDXMLElement *) [DDXMLNode elementWithName:[[MainViewController sharedViewController] rootElement]];
_isGenerateRootTag = FALSE;
}
dispatch_async(dispatch_get_main_queue(), ^{
_timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(timerFireMethod) userInfo:nil repeats:NO];
NSLog(@"**************************STARTING THE TIMER %@**********************",_timer.description);
});
[self sendRequest];
}
Now, i proceed further do my validations and if all the conditions are met i invalidate my timer from some other methods like this
NSLog(@"**************************KILLING TIMER %@ FROM VALIDATE RESPONSE METHOD**********************",_timer.description);
// Invalidate timer..
if (_timer != nil) {
[_timer invalidate];
_timer = nil;
}
If the conditions are not met and 30 sec are passsed my timerFireMethod would get called
- (void)timerFireMethod
{
NSLog(@"Timer Methods Metho gor called with timer Instance %@",_timer.description);
}
This is an intermittent issue, looks like a race condition to me but does happen and causes a lot of problem.. Am i doing something wrong here need your expert advices.. I am stuck
It looks like you have to invalidate the timer before reassigning it source: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/
Once scheduled on a run loop, the timer fires at the specified interval until it is invalidated.
So, do something like
dispatch_async(dispatch_get_main_queue(), ^{
if (timer) {
[_timer invalidate];
_timer = nil;
}
_timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(timerFireMethod) userInfo:nil repeats:NO];
i.e. reassinging the timer is not invaliding the old one, also be sure to
you should always call the invalidate method from the same thread on which the timer was installed.