1

I have a problem about using NSTimer and the code is as below, I have simplified the code:

- (void) mainThreadFun
{
    [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(test) userInfo:nil repeats:YES];

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
           [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:@selector(test1) userInfo:nil repeats:YES];
    });

}

I found that the NSTimer in the mainThread work but the NSTimer in another thread did not work. Why does this happen and how can I fix this?

Sabby
  • 2,586
  • 2
  • 27
  • 41
itenyh
  • 1,921
  • 2
  • 23
  • 38
  • possible duplicate of [How do I create a NSTimer on a background thread?](http://stackoverflow.com/questions/8304702/), [Problem with thread and NSTimer](http://stackoverflow.com/questions/3335114/), [Running a timer within an NSThread](http://stackoverflow.com/questions/2083737/), [Threaded NSTimer](http://stackoverflow.com/questions/3156452/), [NSThread and NSTimer](http://stackoverflow.com/questions/1338891/) – jscs May 30 '12 at 02:39

1 Answers1

5

You cannot use NSTimer on a GCD queue. NSTimer requires an NSRunLoop to operate, and GCD queues do not have an NSRunLoop.

If you want timer functionality with GCD queues, you should be using either dispatch_after() for a one-shot timer, or a dispatch_source for repeating timers.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • @JacquesCousteau: That is incorrect. Queues do not get drained by runloops. The only exception is the main runloop does drain the main queue. You're confused because calling `+[NSRunLoop currentRunLoop]` will actually create one for the current thread if one doesn't exist. But that doesn't mean the runloop is actually running, because it's not. – Lily Ballard May 30 '12 at 04:16
  • @JacquesCousteau: Then either you're actually on the main queue or the documentation is wrong. Try pausing in the debugger and look at the backtrace. NSRunLoop is nowhere to be found. – Lily Ballard May 30 '12 at 04:18
  • @JacquesCousteau: BTW, you may be fooling yourself if you're using a `dispatch_sync()` onto a global queue to test this. `dispatch_sync()` will typically run the block on the current thread if it can. – Lily Ballard May 30 '12 at 04:20
  • @JacquesCousteau: Well yes, of *course* they're on threads. You can't run code outside of a thread. But they have no run loop. Here's a [sample file](https://gist.github.com/2833771) that demonstrates this. The first `dispatch_sync()` will run on thread 1 with a run loop, but the `dispatch_group_async()` runs on thread 2 with no run loop. – Lily Ballard May 30 '12 at 04:25