Question

I have a code snippet like this:

m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                                       target:self
                                                     selector:@selector(activityIndicatorTimer:)
                                                     userInfo:nil
                                                      repeats:NO];

When I call it like so the selector is not fired after the given timeOutInSeconds. However, if I modify it to be like the following, then the selector is called twice.

NSLog(@"Timer set");
m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                               target:self
                                             selector:@selector(activityIndicatorTimer:)
                                             userInfo:nil
                                              repeats:NO];
[[NSRunLoop currentRunLoop] addTimer:m_timer forMode:NSRunLoopCommonModes];

Could anyone offer any suggestion as to what I am likely doing wrong?

I am using XCode 5.1, and building on 7.1.1 iPhone 4S

Was it helpful?

Solution

Call this timer in main thread:

dispatch_async(dispatch_get_main_queue(), ^{
   m_timer = [NSTimer scheduledTimerWithTimeInterval:timeOutInSeconds
                                                   target:self
                                                 selector:@selector(activityIndicatorTimer:)
                                                 userInfo:nil
                                                  repeats:NO];
});

OTHER TIPS

You have 3 options in creating timer, as Apple states in the doc:

  • Use the scheduledTimerWithTimeInterval:invocation:repeats: or scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer and schedule it on the current run loop in the default mode.
  • Use the timerWithTimeInterval:invocation:repeats: or timerWithTimeInterval:target:selector:userInfo:repeats: class method to create the timer object without scheduling it on a run loop. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)
  • Allocate the timer and initialize it using the initWithFireDate:interval:target:selector:userInfo:repeats: method. (After creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.)

The method you are using already schedules the timer on the current loop and you should not schedule another time. In my opinion the problem is elsewhere, try (to make it easy) to put a fixed value instead of timeOutInSeconds.
Also the most common way to call something after a specific delay (that should not repeat) is use dispatch_after:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //YOUR CODE
    });

Where the 2 is an arbitrary interval (in this case 2 seconds).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top