Intro to GCD/Async CocoaCarl Brown CocoaCoders 2015-02-05
Grand Central Dispatch
It’s a switching system you use to get your work done
Let the OS/Library worry about how
Just learn to use it correctly
Threads are like train tracks
Multiple parallel ways for your code to execute
If you’ve done much professional programming, you have some concept of threads
We’re not supposed to use Threads
Apple's Concurrency Programming Guide*:
Page 10: "The Move Away from Threads"
Page 74: "Migrating Away from Threads"
* http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html
The OS manages the thread poolThreads are expensive
It will make/reclaim threads on demand
It does this dynamically to help your programs (as well as the other programs on the system)
If you create your own threads, you get in its way
We’re supposed to use Queues Now
Apple's Concurrency Programming Guide*:
Page 74: "Replacing Threads with Dispatch Queues"
* http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/Introduction/Introduction.html
Queues are like Trains
A collection of tasks (cars) one behind the other being driven by an engine.
(Some queues are parallel, we’re not worrying about those for this discussion).
Queues live on Threads
Any given (serial) Queue Lives on one thread at a time
Queues can be moved between threads
The OS does this for you
So don’t worry about it
Just don’t assume that you’re still on the same thread you were
Or that you’ll stay on the one you are
One Thread (&∴ One Queue) is Magic
The UI/Main Thread is where the UI processes events
Don’t block the UI Thread
Only update or change the UI on the UI Thread
One Queue (&∴ One Thread) is Magic
The Main Queue is where the UI processes events
Don’t block the Main Queue
Only update or change the UI on the Main Queue
Make sure you’re on the right Queue
All UI calls go in dispatch_get_main_queue()
Updating the UI from the wrong queue makes bad things happen
Make sure you’re off the wrong Queue
ONLY UI calls go in dispatch_get_main_queue()
Doing non-UI things on the main queue blocks the UI
Use dispatch_get_global_queue(XX, 0)
Sometimes it’s hard to tell
For example, Core Data Contexts with NSMainQueueConcurrencyType are on the UI Thread because they’re assumed to be communicating with the UI
Updates to them have to be on the main queue
"Rocket Engine" for Responsive Code
NSAssert(![NSThread isMainThread], @"BOOM");
"Rocket Engine" for Responsive CodeNSAssert(![NSThread isMainThread], @"BOOM");
WARNING: Rocket Engines can EXPLODE in testing.
Move a task to the Main/UI Queue
if (![NSThread isMainThread]) { dispatch_async(
dispatch_get_main_queue(), ^{
[self runMethod:args]; }); return; } }
*For Simplicity: I’m not worrying about self-capture retain cycles here.
Move a task OFF the Main/UI Queue
if ([NSThread isMainThread]) { dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
[self runMethod:args]; }); return; } }
*For Simplicity: I’m not worrying about self-capture retain cycles here.
NSOperation
Been around since the first iPhone OS SDK
Way to encapsulate the pieces of a task in one place
Can be queried, suspended or canceled
Simple selector call or block variants
NSOperations are placed in NSOperationQueues
NSOperationQueueLong-lived (presumably) queue that can contain numerous operations
Can be serial or concurrent
Can be suspended or canceled
Nice (but verbose) Objective-C syntax
Will stay on the same thread, if serial
[NSOperationQueue mainQueue] is always on the Main Thread
Dispatch Queues
C-style (concise) syntax
quicker to use in-place
much less typing than declaring an NSOperation and adding to Queue
Harder to manage or cancel
Which to use?No hard-and-fast rules, but...
I tend to use NSOperations for:
things I'm going to do several times
things that have non-trivial complexity
I tend to use dispatch_async() for things:
with less than 10 or so lines of code
done only once in the App
that won't need to change when spec changes
Questions? Discussion?