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 NSLog
s, both of which are printed. I've checked timer
--it is not nil
.
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...
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With