Grand Central Dispatch (GCD) dispatch queues are a powerful tool for performing tasks. Dispatch queues let you execute arbitrary blocks of code either asynchronously or synchronously with respect to the caller.
2. Asynchronous execution
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
Submits a block for asynchronous execution on a dispatch queue and returns immediately.
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
Submits a block object for execution on a dispatch queue and waits until that block completes.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/* The block to submit to the target dispatch queue. */
});
3. Running in separate thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
/* Run in background thread */
dispatch_sync(dispatch_get_main_queue(), ^{
/* Run in main thread
Waits until completes */
});
/* Continue in background thread */
});
5. Queues
• Serial (private dispatch queues)
Serial queues execute one task at a time in the order in which they are added
to the queue.
• Concurrent (global dispatch queue)
Concurrent queues execute one or more tasks concurrently
• Main dispatch queue
The main dispatch queue is a globally available serial queue that executes
tasks on the application’s main thread
6. Common queues
• Main queue (serial)
dispatch_get_main_queue() returns the main queue
• Concurrent queues with the specified quality of service class
1. DISPATCH_QUEUE_PRIORITY_HIGH
2. DISPATCH_QUEUE_PRIORITY_DEFAULT
3. DISPATCH_QUEUE_PRIORITY_LOW
4. DISPATCH_QUEUE_PRIORITY_BACKGROUND
dispatch_get_global_queue() returns a system-defined global concurrent
queue
8. Memory managment
• Before macOS 10.8 or iOS v6.0 – MRC
dispatch_retain(serialQueue);
dispatch_release(serialQueue);
• Later – ARC
9. Adding tasks to a queue
- (void)gcd {
dispatch_queue_t myCustomQueue;
myCustomQueue = dispatch_queue_create("com.example.MyCustomQueue", NULL);
dispatch_async(myCustomQueue, ^{
printf("Do some work here.n");
});
printf("The first block may or may not have run.n");
dispatch_sync(myCustomQueue, ^{
printf("Do some more work here.n");
});
printf("Both blocks have completed.n");
}
The first block may or may not have run.
Do some work here.
Do some more work here.
Both blocks have completed.
12. dispatch_time
/*!
* @typedef dispatch_time_t
*
* @abstract
* A somewhat abstract representation of time; where zero means "now" and
* DISPATCH_TIME_FOREVER means "infinity" and every value in between is an
* opaque encoding.
*/
typedef uint64_t dispatch_time_t;
#define DISPATCH_TIME_NOW (0ull)
#define DISPATCH_TIME_FOREVER (~0ull)
dispatch_time_t dispatch_time(dispatch_time_t when, int64_t delta);
Creates a dispatch_time_t relative to the default clock or modifies an existing dispatch_function_t.
• when – The value to use as the basis for a new value
• delta – The number of nanoseconds to add to the time in the when parameter.
20. Semaphore
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue”,
DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue , ^{
NSLog(@"Looooooong opetation....");
[NSThread sleepForTimeInterval:2.0];
NSLog(@"signal");
dispatch_semaphore_signal(sema);
});
NSLog(@"wait for signal");
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"some shit");
wait for signal
Looooooong opetation....
signal
some shit
21. dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@”Diana is sleeping");
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@“Diana is waking up ;)");
[NSThread sleepForTimeInterval:1.0];
NSLog(@“Diana calls David!");
dispatch_semaphore_signal(sema);
});
dispatch_async(queue, ^{
NSLog(@”David is sleeping");
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@“David is waking up =)");
dispatch_semaphore_signal(sema);
[NSThread sleepForTimeInterval:1.0];
NSLog(@“David calls Diana!");
dispatch_semaphore_signal(sema);
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2.0];
NSLog(@“They are sleeping");
NSLog(@”Nightmare");
dispatch_semaphore_signal(sema);
});
Diana is sleeping
David is sleeping
They are sleeping
Nightmare
Diana is waking up ;)
Diana calls David!
David is waking up =)
David calls Diana!
what happened if dispatch_semaphore_create(1)? Or (-1)?