2. 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
3. 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
4. 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
5. The OS manages the thread pool
Threads 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
6. 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
7. 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).
8. Queues live on Threads
Any given (serial) Queue Lives on
one thread at a time
9. 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
10. 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
11. 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
12. 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
13. 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)
14. 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
15. "Rocket Engine" for Responsive Code
NSAssert(![NSThread isMainThread], @"BOOM");
16. "Rocket Engine" for Responsive Code
NSAssert(![NSThread isMainThread], @"BOOM");
WARNING: Rocket Engines can EXPLODE in testing.
17. 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.
18. 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.
19. 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
20. NSOperationQueue
Long-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
21. 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
22. 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