1

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

user2606782
  • 260
  • 1
  • 5
  • 15

1 Answers1

0

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.

Alex
  • 3,861
  • 5
  • 28
  • 44
  • But presumably that doesn't provide the 30-second timeout the OP is looking for once `createAPIXML` has been invoked? – Droppy Oct 07 '15 at 16:16
  • In the above comments he mentions it gets called repeatedly, I'm assuming a previous timer is being fired that he is assuming has been invalidated – Alex Oct 07 '15 at 16:18
  • Ah I see; you are probably better off putting the invalidation code in your answer rather than the comment. – Droppy Oct 07 '15 at 16:18
  • @Droppy he does list a perfectly valid invalidation method in his own post, but I suppose you are right! thanks – Alex Oct 07 '15 at 16:19
  • What can i do to verify which timer instance got my timerFireMethod to fire?? I could probably narrow down the problem then .. i.e i know the timer object which got created when i scheduled the timer.. is there a way i can find/debug association between timer object and timerFireMethod?? – user2606782 Oct 07 '15 at 16:30
  • Or, if multiple timers need to be running concurrently, OP needs to create an array of timers and keep track of them. – Stonz2 Oct 07 '15 at 17:23
  • @user2606782 I'm not sure how to do that, but since you are only using one timer then that 'should be' the one firing. Stonz2's comment is correct, if you want multiple timers you will need to keep them in an array – Alex Oct 07 '15 at 18:55
  • @Alex - If i use my selector method like this timerFireMethod:(NStimer *)timer which takes in timer as argument then is this timer argument be the same which got created when we scheduled the timer.. Probably this would solve my problem....What do u think?? – user2606782 Oct 07 '15 at 19:45
  • @user2606782 I suppose that is probably the case... although wasn't that why you posted this question originally... because that was the problem? – Alex Oct 07 '15 at 21:27
  • actually yes... wanted to be sure. – user2606782 Oct 08 '15 at 04:48
  • @user2606782 if you believe my answer answered your original question you should mark it as correct – Alex Oct 08 '15 at 12:34