GarlicFries
GarlicFries

Reputation: 8333

GCD timer never fires

I have a bare single-view iOS app with the following in the -viewDidLoad of the view:

dispatch_queue_t q_default;
q_default = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, q_default); //run event handler on the default global queue
dispatch_time_t now = dispatch_walltime(DISPATCH_TIME_NOW, 0);
dispatch_source_set_timer(timer, now, 30ull*NSEC_PER_SEC, 5000ull);
dispatch_source_set_event_handler(timer, ^{
    printf("test\n");
});
dispatch_resume(timer);

This is taken directly from the docs (except for a simplified printf() argument). The block is never executed--can someone tell me why??

Additional Information

I was trying this in a larger app to no avail. I then backed out to the barebones app, tried with ARC both on and off, tried this code in -appDidFinishLaunching..., all with no luck. I can surround this code with NSLogs, both of which are printed. I've checked timer--it is not nil.

Upvotes: 5

Views: 1380

Answers (2)

GarlicFries
GarlicFries

Reputation: 8333

So, the problem was that I'd lost my reference to timer when the surrounding scope was destroyed. Changing timer to an ivar instead of an automatic variable fixed things...

Upvotes: 6

Tommy
Tommy

Reputation: 100652

Per the documentation of dispatch_source_create:

Dispatch sources are created in a suspended state. After creating the source and setting any desired attributes (for example, the handler or the context), your application must call dispatch_resume to begin event delivery.

So your timer never fires because it's suspended. To end its suspension you need to call dispatch_resume.

Upvotes: 4

Related Questions