SlideShare a Scribd company logo
Grand Central Dispatch
Павел Альбицкий
p.albitsky@gmail.com
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. */
});
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 */
});
Queue
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
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
Creating queues
• Concurrent
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_CONCURRENT);
• Serial
dispatch_queue_t serialQueue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_SERIAL);
#define DISPATCH_QUEUE_SERIAL NULL
Memory managment
• Before macOS 10.8 or iOS v6.0 – MRC

dispatch_retain(serialQueue);
dispatch_release(serialQueue);
• Later – ARC

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.
dispatch_once
typedef long dispatch_once_t;
static dispatch_once_t tokenOnce;
dispatch_once(&tokenOnce, ^{
printf("tokenOnce: %ld", tokenOnce);
tokenOnce = 0;
});
tokenOnce: 140734581496400
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(), ^{
//
});
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.
Multiple invocations
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"%@ , %zu",[NSDate date], index);
});
2016-02-16 21:47:38 +0000 , 4
2016-02-16 21:47:38 +0000 , 7
2016-02-16 21:47:38 +0000 , 3
2016-02-16 21:47:38 +0000 , 1
2016-02-16 21:47:38 +0000 , 5
2016-02-16 21:47:38 +0000 , 0
2016-02-16 21:47:38 +0000 , 2
2016-02-16 21:47:38 +0000 , 6
2016-02-16 21:47:38 +0000 , 8
2016-02-16 21:47:38 +0000 , 9
DISPATCH_QUEUE_CONCURRENT -> NULL ?
Parallelize Your for Loops
for (i = 0; i < count; i++) {
results[i] = do_work(data, i);
}
total = summarize(results, count);
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_apply(count, queue, ^(size_t i){
results[i] = do_work(data, i);
});
total = summarize(results, count);
Suspend and resut queue
dispatch_suspend(queue);
dispatch_resume(queue);
Group notify
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^ {
NSLog(@"Block1 Start");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"Block1 End");
});
dispatch_group_async(group, queue, ^ {
NSLog(@"Block2 Start");
[NSThread sleepForTimeInterval:8.0];
NSLog(@"Block2 End");
});
dispatch_group_notify(group, queue, ^ {
NSLog(@"Block3 thread: %@", [NSThread currentThread]);
});
Block2 Start
Block1 Start
Block1 End
Block2 End
Block3 thread: <NSThread: 0x7fe08a10f0a0>{number = 2, name = (null)}
dispatch_group_wait
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue",
DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^ {
NSLog(@"Block1 Start");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"Block1 End");
});
dispatch_group_async(group, queue, ^ {
NSLog(@"Block2 Start");
[NSThread sleepForTimeInterval:8.0];
NSLog(@"Block2 End");
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"thread: %@", [NSThread currentThread]);
Block2 Start
Block1 Start
Block1 End
Block2 End
Block3 thread: <NSThread: 0x7fa88b502490>{number = 1, name = main}
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
dispatch_group_t downloadGroup = dispatch_group_create();
for (NSInteger i = 0; i < 3; i++) {
NSURL *url;
switch (i) {
case 0:
url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString];
break;
case 1:
url = [NSURL URLWithString:kSuccessKidURLString];
break;
}
dispatch_group_enter(downloadGroup);
Photo *photo = [[Photo alloc] initwithURL:url
withCompletionBlock:^(UIImage *image, NSError *_error) {
dispatch_group_leave(downloadGroup);
}];
[[PhotoManager sharedManager] addPhoto:photo];
}
dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
if (completionBlock) {
completionBlock(error);
}
});
});
dispatch_group_enter, dispatch_group_leave
Barrier
dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue”,
DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"Block1 Start");
[NSThread sleepForTimeInterval:3.0];
NSLog(@"Block1 End");
});
dispatch_async(queue, ^{
NSLog(@"Block2 Start");
[NSThread sleepForTimeInterval:2.0];
NSLog(@"Block2 End");
});
dispatch_barrier_async(queue, ^{
NSLog(@"Block3 thread: %@", [NSThread currentThread]);
});
Block2 Start
Block1 Start
Block2 End
Block1 End
Block3 thread: <NSThread: 0x7f8452e1a1d0>{number = 2, name = (null)}
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
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)?
Спасибо за внимание!
Павел Альбицкий
p.albitsky@gmail.com

More Related Content

What's hot

Replication of virus
Replication of virusReplication of virus
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
Cakra Danu Sedayu
 
Celery
CeleryCelery
Celery
Fatih Erikli
 
15. DateTime API.ppt
15. DateTime API.ppt15. DateTime API.ppt
15. DateTime API.ppt
VISHNUSHANKARSINGH3
 
SWTBot Tutorial
SWTBot TutorialSWTBot Tutorial
SWTBot Tutorial
Chris Aniszczyk
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
Nir Kaufman
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
Christoffer Noring
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
Vadims Savjolovs
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]
Kuro Hsu
 
Maven
MavenMaven
Maven
Emprovise
 
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
Kohki Miki
 
忙しい人のためのBackbone.jsとAngular.js入門
忙しい人のためのBackbone.jsとAngular.js入門忙しい人のためのBackbone.jsとAngular.js入門
忙しい人のためのBackbone.jsとAngular.js入門
Toshiaki Maki
 
Dietetyk 321[11] z2.09_u
Dietetyk 321[11] z2.09_uDietetyk 321[11] z2.09_u
Dietetyk 321[11] z2.09_u
gemix gemix
 
Data processing with celery and rabbit mq
Data processing with celery and rabbit mqData processing with celery and rabbit mq
Data processing with celery and rabbit mq
Jeff Peck
 
Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014
Ippon
 
State manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to VuexState manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to Vuex
Commit University
 

What's hot (18)

Replication of virus
Replication of virusReplication of virus
Replication of virus
 
Build RESTful API Using Express JS
Build RESTful API Using Express JSBuild RESTful API Using Express JS
Build RESTful API Using Express JS
 
Express node js
Express node jsExpress node js
Express node js
 
Celery
CeleryCelery
Celery
 
15. DateTime API.ppt
15. DateTime API.ppt15. DateTime API.ppt
15. DateTime API.ppt
 
SWTBot Tutorial
SWTBot TutorialSWTBot Tutorial
SWTBot Tutorial
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Learning Svelte
Learning SvelteLearning Svelte
Learning Svelte
 
Structured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin CoroutinesStructured concurrency with Kotlin Coroutines
Structured concurrency with Kotlin Coroutines
 
第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]第一次用 Vue.js 就愛上 [改]
第一次用 Vue.js 就愛上 [改]
 
Maven
MavenMaven
Maven
 
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
 
7
77
7
 
忙しい人のためのBackbone.jsとAngular.js入門
忙しい人のためのBackbone.jsとAngular.js入門忙しい人のためのBackbone.jsとAngular.js入門
忙しい人のためのBackbone.jsとAngular.js入門
 
Dietetyk 321[11] z2.09_u
Dietetyk 321[11] z2.09_uDietetyk 321[11] z2.09_u
Dietetyk 321[11] z2.09_u
 
Data processing with celery and rabbit mq
Data processing with celery and rabbit mqData processing with celery and rabbit mq
Data processing with celery and rabbit mq
 
Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014Formation Spring Avancé gratuite par Ippon 2014
Formation Spring Avancé gratuite par Ippon 2014
 
State manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to VuexState manager in Vue.js, from zero to Vuex
State manager in Vue.js, from zero to Vuex
 

Similar to Grand Central Dispatch in Objective-C

.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
Karel Zikmund
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
Karel Zikmund
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
bradburgess22840
 
Grand Central Dispatch
Grand Central DispatchGrand Central Dispatch
Grand Central Dispatchcqtt191
 
RTOS.pptx
RTOS.pptxRTOS.pptx
RTOS.pptx
IrshanNazir3
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
GlobalLogic Ukraine
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
Adam Dudczak
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
Giordano Scalzo
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
João Esperancinha
 
エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理maruyama097
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
Rodrigo Almeida
 
Multithreading in Java
Multithreading in JavaMultithreading in Java
Multithreading in Java
Appsterdam Milan
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?
Artur Latoszewski
 
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
odiliagilby
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/OJussi Pohjolainen
 
Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!Michael Barker
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
JAX London
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
DroidConTLV
 
Standard Template Library (STL) in Object Oriented Programming
Standard Template Library (STL) in Object Oriented ProgrammingStandard Template Library (STL) in Object Oriented Programming
Standard Template Library (STL) in Object Oriented Programming
Mandeep Singh
 

Similar to Grand Central Dispatch in Objective-C (20)

.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
.NET Core Summer event 2019 in Brno, CZ - Async demystified -- Karel Zikmund
 
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel ZikmundNDC Sydney 2019 - Async Demystified -- Karel Zikmund
NDC Sydney 2019 - Async Demystified -- Karel Zikmund
 
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Grand Central Dispatch
Grand Central DispatchGrand Central Dispatch
Grand Central Dispatch
 
RTOS.pptx
RTOS.pptxRTOS.pptx
RTOS.pptx
 
C++11 - STL Additions
C++11 - STL AdditionsC++11 - STL Additions
C++11 - STL Additions
 
Are we ready to Go?
Are we ready to Go?Are we ready to Go?
Are we ready to Go?
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
 
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptxDecoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
Decoding Kotlin - Your guide to solving the mysterious in Kotlin.pptx
 
エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理エンタープライズ・クラウドと 並列・分散・非同期処理
エンタープライズ・クラウドと 並列・分散・非同期処理
 
Thread
ThreadThread
Thread
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
 
Multithreading in Java
Multithreading in JavaMultithreading in Java
Multithreading in Java
 
Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?Kotlin coroutine - the next step for RxJava developer?
Kotlin coroutine - the next step for RxJava developer?
 
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
__MACOSX._assign3assign3.DS_Store__MACOSXassign3._.D.docx
 
.NET Multithreading and File I/O
.NET Multithreading and File I/O.NET Multithreading and File I/O
.NET Multithreading and File I/O
 
Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!Lock? We don't need no stinkin' locks!
Lock? We don't need no stinkin' locks!
 
Locks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael BarkerLocks? We Don't Need No Stinkin' Locks - Michael Barker
Locks? We Don't Need No Stinkin' Locks - Michael Barker
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
Standard Template Library (STL) in Object Oriented Programming
Standard Template Library (STL) in Object Oriented ProgrammingStandard Template Library (STL) in Object Oriented Programming
Standard Template Library (STL) in Object Oriented Programming
 

Grand Central Dispatch in Objective-C

  • 1. Grand Central Dispatch Павел Альбицкий p.albitsky@gmail.com
  • 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
  • 7. Creating queues • Concurrent dispatch_queue_t concurrentQueue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); • Serial dispatch_queue_t serialQueue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_SERIAL); #define DISPATCH_QUEUE_SERIAL NULL
  • 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.
  • 10. dispatch_once typedef long dispatch_once_t; static dispatch_once_t tokenOnce; dispatch_once(&tokenOnce, ^{ printf("tokenOnce: %ld", tokenOnce); tokenOnce = 0; }); tokenOnce: 140734581496400
  • 11. 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(), ^{ // });
  • 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.
  • 13. Multiple invocations dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_apply(10, queue, ^(size_t index) { NSLog(@"%@ , %zu",[NSDate date], index); }); 2016-02-16 21:47:38 +0000 , 4 2016-02-16 21:47:38 +0000 , 7 2016-02-16 21:47:38 +0000 , 3 2016-02-16 21:47:38 +0000 , 1 2016-02-16 21:47:38 +0000 , 5 2016-02-16 21:47:38 +0000 , 0 2016-02-16 21:47:38 +0000 , 2 2016-02-16 21:47:38 +0000 , 6 2016-02-16 21:47:38 +0000 , 8 2016-02-16 21:47:38 +0000 , 9 DISPATCH_QUEUE_CONCURRENT -> NULL ?
  • 14. Parallelize Your for Loops for (i = 0; i < count; i++) { results[i] = do_work(data, i); } total = summarize(results, count); dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_apply(count, queue, ^(size_t i){ results[i] = do_work(data, i); }); total = summarize(results, count);
  • 15. Suspend and resut queue dispatch_suspend(queue); dispatch_resume(queue);
  • 16. Group notify dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^ { NSLog(@"Block1 Start"); [NSThread sleepForTimeInterval:5.0]; NSLog(@"Block1 End"); }); dispatch_group_async(group, queue, ^ { NSLog(@"Block2 Start"); [NSThread sleepForTimeInterval:8.0]; NSLog(@"Block2 End"); }); dispatch_group_notify(group, queue, ^ { NSLog(@"Block3 thread: %@", [NSThread currentThread]); }); Block2 Start Block1 Start Block1 End Block2 End Block3 thread: <NSThread: 0x7fe08a10f0a0>{number = 2, name = (null)}
  • 17. dispatch_group_wait dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^ { NSLog(@"Block1 Start"); [NSThread sleepForTimeInterval:5.0]; NSLog(@"Block1 End"); }); dispatch_group_async(group, queue, ^ { NSLog(@"Block2 Start"); [NSThread sleepForTimeInterval:8.0]; NSLog(@"Block2 End"); }); dispatch_group_wait(group, DISPATCH_TIME_FOREVER); NSLog(@"thread: %@", [NSThread currentThread]); Block2 Start Block1 Start Block1 End Block2 End Block3 thread: <NSThread: 0x7fa88b502490>{number = 1, name = main}
  • 18. dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ dispatch_group_t downloadGroup = dispatch_group_create(); for (NSInteger i = 0; i < 3; i++) { NSURL *url; switch (i) { case 0: url = [NSURL URLWithString:kOverlyAttachedGirlfriendURLString]; break; case 1: url = [NSURL URLWithString:kSuccessKidURLString]; break; } dispatch_group_enter(downloadGroup); Photo *photo = [[Photo alloc] initwithURL:url withCompletionBlock:^(UIImage *image, NSError *_error) { dispatch_group_leave(downloadGroup); }]; [[PhotoManager sharedManager] addPhoto:photo]; } dispatch_group_wait(downloadGroup, DISPATCH_TIME_FOREVER); dispatch_async(dispatch_get_main_queue(), ^{ if (completionBlock) { completionBlock(error); } }); }); dispatch_group_enter, dispatch_group_leave
  • 19. Barrier dispatch_queue_t queue = dispatch_queue_create("com.myapp.queue”, DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"Block1 Start"); [NSThread sleepForTimeInterval:3.0]; NSLog(@"Block1 End"); }); dispatch_async(queue, ^{ NSLog(@"Block2 Start"); [NSThread sleepForTimeInterval:2.0]; NSLog(@"Block2 End"); }); dispatch_barrier_async(queue, ^{ NSLog(@"Block3 thread: %@", [NSThread currentThread]); }); Block2 Start Block1 Start Block2 End Block1 End Block3 thread: <NSThread: 0x7f8452e1a1d0>{number = 2, name = (null)}
  • 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)?
  • 22. Спасибо за внимание! Павел Альбицкий p.albitsky@gmail.com