With Core Foundation, you can invoke a selector in an object after a
given period of time, using the performSelector:withObject:afterDelay:
method of
the NSObject
class. Here is an
example:
- (void) printString:(NSString *)paramString{ NSLog(@"%@", paramString); } - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ @selector(performSelector:withObject:afterDelay:) [self performSelector:@selector(printString:) withObject:@"Grand Central Dispatch" afterDelay:3.0]; // Override point for customization after application launch. [self.window makeKeyAndVisible]; return YES; }
In this example we are asking the runtime to call the printString:
method after 3 seconds of delay. We can do the same thing
in GCD using the dispatch_after
and
dispatch_after_f
functions, each of
which is described here:
dispatch_after
Dispatches a block object to a dispatch queue after a given period of time, specified in nanoseconds. These are the parameters that this function requires:
The number of nanoseconds GCD has to wait on a given dispatch queue (specified by the second parameter) before it executes the given block object (specified by the third parameter).
The dispatch queue on which the block object (specified by the third parameter) has to be executed after the given delay (specified by the first parameter).
The block object to be invoked after the specified number of nanoseconds on the given dispatch queue. This block object should have no return value and should accept no parameters (see Constructing Block Objects and Their Syntax).
dispatch_after_f
Dispatches a C function to GCD for execution after a given period of time, specified in nanoseconds. This function accepts four parameters:
The number of nanoseconds GCD has to wait on a given dispatch queue (specified by the second parameter) before it executes the given function (specified by the fourth parameter).
The dispatch queue on which the C function (specified by the fourth parameter) has to be executed after the given delay (specified by the first parameter).
The memory address of a value in the heap to be passed to the C function (for an example, see Performing UI-Related Tasks).
The address of the C function that has to be executed after a certain period of time (specified by the first parameter) on the given dispatch queue (specified by the second parameter).
Although the delays are in nanoseconds, it is up to iOS to decide the granularity of dispatch delay, and this delay might not be as precise as what you hope when you specify a value in nanoseconds.
Let’s have a look at an example for dispatch_after
first:
double delayInSeconds = 2.0; dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_after(delayInNanoSeconds, concurrentQueue, ^(void){ /* Perform your operations here */ });
As you can see, the nanoseconds delay parameter for both the
dispatch_after
and dispatch_after_f
functions has to be of type
dispatch_time_t
, which is an abstract
representation of absolute time. To get the value for this parameter, you
can use the dispatch_time
function as
demonstrated in this sample code. Here are the parameters that you can
pass to the dispatch_time
function:
If this value was denoted with B and the
delta parameter was denoted with D, the
resulting time from this function would be equal to
B+D. You can set this
parameter’s value to DISPATCH_TIME_NOW
to denote
now as the base time and then specify the delta
from now using the delta parameter.
This parameter is the nanoseconds that will get added to the base time parameter to create the result of this function.
For example, to denote a time 3 seconds from now, you could write your code like so:
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 3.0f * NSEC_PER_SEC);
Or to denote half a second from now:
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (1.0 / 2.0f) * NSEC_PER_SEC);
Now let’s have a look at how we can use the dispatch_after_f
function:
void processSomething(void *paramContext){ /* Do your processing here */ NSLog(@"Processing..."); } - (BOOL) application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ double delayInSeconds = 2.0; dispatch_time_t delayInNanoSeconds = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_after_f(delayInNanoSeconds, concurrentQueue, NULL, processSomething); // Override point for customization after application launch. [self.window makeKeyAndVisible]; return YES; }