Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-C delay action with blocks

I know that there are several ways of delaying an action in Objective-C like:

performSelector:withObject:afterDelay:

or using NSTimer.

But there is such a fancy thing called blocks where you can do something like this:

[UIView animateWithDuration:1.50 delay:0 options:(UIViewAnimationOptionCurveEaseOut|UIViewAnimationOptionBeginFromCurrentState) animations:^{

    }completion:^(BOOL finished){
}];

Unfortunately, this method applies only to animating things.

How can I create a delay with a block in one method so I don't have to use all those @selectors and without the need to create a new separate method? Thanks!

like image 208
Sergey Grischyov Avatar asked Mar 14 '13 15:03

Sergey Grischyov


3 Answers

use dispatch_after:

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
    //code to be executed on the main queue after delay
    [self doSometingWithObject:obj1 andAnotherObject:obj2];
});
like image 200
Martin Ullrich Avatar answered Oct 20 '22 00:10

Martin Ullrich


Expanding on the accepted answer, I created a Helper function for anyone who doesn't care to memorize the syntax each time they want to do this :) I simply have a Utils class with this:

Usage:

[Utils delayCallback:^{
     //--- code here
} forTotalSeconds:0.3];

Helper method:

+ (void) delayCallback: (void(^)(void))callback forTotalSeconds: (double)delayInSeconds{

     dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
     dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
           if(callback){
                callback();
           }
      });
}
like image 33
rckehoe Avatar answered Oct 20 '22 00:10

rckehoe


Xcode 11.3.1 (at least, and also other versions of Xcode) provides a code snippet to do this where you just have to enter the delay value and the code you wish to run after the delay.

  1. click on the + button at the top right of Xcode.
  2. search for after
  3. It will return only 1 search result, which is the desired snippet (see screenshot). Double click it and you're good to go.

screenshot illustrating how to get the snippet from within Xcode itself

like image 39
auspicious99 Avatar answered Oct 19 '22 22:10

auspicious99