Objective-C delay action with blocks

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];
});

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


Here is how you can trigger a block after a delay in Swift:

runThisAfterDelay(seconds: 4) { () -> () in
    print("Prints this 4 seconds later in main queue")
    // Or just call animatedMyObject() right here
}

/// EZSwiftExtensions
func runThisAfterDelay(seconds seconds: Double, after: () -> ()) {
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue(), after)
}

Its included as a standard function in my repo: https://github.com/goktugyil/EZSwiftExtensions


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();
           }
      });
}