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

Is there a way to call a block with a primitive parameter after a delay, like using performSelector:withObject:afterDelay: but with an argument like int/double/float?


I think you're looking for dispatch_after(). It requires your block to accept no parameters, but you can just let the block capture those variables from your local scope instead.

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_main_queue(), ^{
    NSLog(@"parameter1: %d parameter2: %f", parameter1, parameter2);
});

More: https://developer.apple.com/documentation/dispatch/1452876-dispatch_after


You can use dispatch_after to call a block later. In Xcode, start typing dispatch_after and hit Enter to autocomplete to the following:

enter image description here

Here's an example with two floats as "arguments." You don't have to rely on any type of macro, and the intent of the code is quite clear:

Swift 3, Swift 4

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
    print("Sum of times: \(time1 + time2)")
}

Swift 2

let time1 = 8.23
let time2 = 3.42

// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
        println("Sum of times: \(time1 + time2)")
}

Objective C

CGFloat time1 = 3.49;
CGFloat time2 = 8.13;

// Delay 2 seconds
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    CGFloat newTime = time1 + time2;
    NSLog(@"New time: %f", newTime);
});

How about using Xcode built-in code snippet library?

enter image description here

Update for Swift:

Many up votes inspired me to update this answer.

The build-in Xcode code snippet library has dispatch_after for only objective-c language. People can also create their own Custom Code Snippet for Swift.

Write this in Xcode.

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(<#delayInSeconds#> * Double(NSEC_PER_SEC))), dispatch_get_main_queue(), {
        <#code to be executed after a specified delay#>
    })

Drag this code and drop it in the code snippet library area. enter image description here

Bottom of the code snippet list, there will be a new entity named My Code Snippet. Edit this for a title. For suggestion as you type in the Xcode fill in the Completion Shortcut.

For more info see CreatingaCustomCodeSnippet.

Update Swift 3

Drag this code and drop it in the code snippet library area.

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(<#delayInSeconds#>)) {
    <#code to be executed after a specified delay#>
}

Expanding on Jaime Cham's answer I created a NSObject+Blocks category as below. I felt these methods better matched the existing performSelector: NSObject methods

NSObject+Blocks.h

#import <Foundation/Foundation.h>

@interface NSObject (Blocks)

- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay;

@end

NSObject+Blocks.m

#import "NSObject+Blocks.h"

@implementation NSObject (Blocks)

- (void)performBlock:(void (^)())block
{
    block();
}

- (void)performBlock:(void (^)())block afterDelay:(NSTimeInterval)delay
{
    void (^block_)() = [block copy]; // autorelease this if you're not using ARC
    [self performSelector:@selector(performBlock:) withObject:block_ afterDelay:delay];
}

@end

and use like so:

[anyObject performBlock:^{
    [anotherObject doYourThings:stuff];
} afterDelay:0.15];