Continue after GCD Note 1.

dispatch_after

The method dispatch_after works like a delayed dispatch_async. The dispatch_after() function submits the block to the given queue at the time specified by the when parameter.

Example:

1
2
3
4
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);
dispatch_after(delay, dispatch_get_main_queue(), ^{
//do something on main thread after 2 sec
});

dispatch group

Dispatch group is used to do some updates after a group of tasks. The tasks in the group can be either asynchronous or synchronous. To create a group:

1
dispatch_group_t group = dispatch_group_create();

There are two ways to add tasks to the group. The first way is adding a block of code to the group, and executing on a specified queue like globe queue:

1
2
3
4
5
6
7
dispatch_group_async(group,specifiedQueue,^{
// do something 1 here
});
dispatch_group_async(group,specifiedQueue,^{
// do something 2 here
});
...

But this is not suitable for something you want to have callback straight away.

The second way is to set starting and ending manually by using dispatch_group_enter() and dispatch_group_leaving().

Suppose we need to download an image with its thumbnail and the original image from a server with different URLs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dispatch_group_t group = dispatch_group_create();
for (NSInteger i = 0; i < 2; i++) {
NSURL *url;
switch (i) {
case 0:
url = [NSURL URLWithString:thumbnailURLString];
break;
case 1:
url = [NSURL URLWithString:orignalURLString];
break;
default:
break;
}
dispatch_group_enter(group);
UIImage *image = [ImageDownloader alloc] initWithURL: url withCompletion:^(NSError *error) {
if (error) {
// handle the error
}
dispatch_grounp_leave(group);
}];

// store the images some where
}

Notice that the number of enter should be equal to the number of leave.

Then, how to notify that the group is finished. There are also two ways. First one, using dispatch_group_wait().

1
2
dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);
// do something after group is finished

This method will return a long value if the time expired before all tasks are finished, and it will block the current thread.

The second way is to use dispatch_group_notify():

1
2
3
dispatch_group_notify(dispatch_group_t group, specifiedQueue,^{
// do something here on the specifiedQueue
});

The dispatch_group_notify() function provides asynchronous notification of the completion of the blocks associated with the group by submitting the block to the specified queue once all blocks associated with the group have completed.