7

I am developing an app where i want to call method in separate queue using dispatch_async. I want to call that method repeatedly after certain interval of time. But the method is not getting called.

I don't know whats wrong. Here is my code:

dispatch_async( NotificationQueue, ^{

        NSLog(@"inside queue");
        timer = [NSTimer scheduledTimerWithTimeInterval: 20.0
                                                 target: self
                                               selector: @selector(gettingNotification)
                                               userInfo: nil
                                                repeats: YES];

        dispatch_async( dispatch_get_main_queue(), ^{
            // Add code here to update the UI/send notifications based on the
            // results of the background processing

        });
    });

-(void)gettingNotification {
    NSLog(@"calling method ");
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
user2185354
  • 519
  • 7
  • 23

3 Answers3

12

If you want a repeating timer to be invoked on a dispatch_queue_t, use dispatch_source_create with a DISPATCH_SOURCE_TYPE_TIMER:

dispatch_queue_t  queue = dispatch_queue_create("com.firm.app.timer", 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), 20ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC);

dispatch_source_set_event_handler(timer, ^{

    // stuff performed on background queue goes here

    NSLog(@"done on custom background queue");

    // if you need to also do any UI updates, synchronize model updates,
    // or the like, dispatch that back to the main queue:

    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"done on main queue");
    });
});

dispatch_resume(timer);

That creates a timer that runs once every 20 seconds (3rd parameter to dispatch_source_set_timer), with a leeway of a one second (4th parameter to dispatch_source_set_timer).

To cancel this timer, use dispatch_source_cancel:

dispatch_source_cancel(timer);
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Just adding the above to a view did load in a vc does not generate any console output, what is missing? – David Karlsson Dec 19 '14 at 23:23
  • 1
    @DavidKarlsson the `timer` variable actually has to be a class property (or ivar). Unlike `NSTiner`, if it falls out of scope, the dispatch timer is canceled and deallocated. – Rob Dec 19 '14 at 23:28
2

Try this code

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    dispatch_async( dispatch_get_main_queue(), ^{

        timer = [NSTimer scheduledTimerWithTimeInterval: 1.0 target: self
                                               selector: @selector(gettingNotification) userInfo: nil repeats: YES];
        // Add code here to update the UI/send notifications based on the
        // results of the background processing

    });
});

-(void)gettingNotification {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
         //background task here
    dispatch_async( dispatch_get_main_queue(), ^{
        // update UI here
        );
});
}
Anand Suthar
  • 3,678
  • 2
  • 30
  • 52
  • 1
    This is also correct, though dispatch source is probably more direct mechanism. This answer could be simplified, though, as there's no point in dispatching the creation of the timer to a background queue and then to the main queue. Just create the repeating timer in the main queue without the two nested dispatches. Still, +1. – Rob Nov 15 '13 at 16:48
0
int parameter1 = 12;
float parameter2 = 144.1;

// Delay execution of my block for 10 seconds.
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC), dispatch_get_current_queue(), ^{
    NSLog(@"parameter1: %d parameter2: %f", parameter1, parameter2);
});

look for more

How do you trigger a block after a delay, like -performSelector:withObject:afterDelay:?

Community
  • 1
  • 1
Retro
  • 3,985
  • 2
  • 17
  • 41