Upload
ben-asher
View
560
Download
0
Embed Size (px)
Citation preview
Grand Central DispatchBen Asher
[email protected] on Github and Twitter
Yelp’s Mission:Connecting people with great
local businesses.
2
Yelp Stats:As of Q2 2015
83M 3268%83M
3
A Responsive App
- Responsive UI
- Don’t make the user wait
4
GCD - Getting Started
Basics of blocks in Objective-C
5
- Segment of code
- Passed around as parameters
- Stored in variables
- Called like C functions ()
^{
// Some code
};
What is GCD about?
“…technology that you use to manage the execution of tasks in your app…”
- Apple Docs
6
- C API (mostly)
- Open source!
- Task = ^{}
GCD - Intro
7
- Schedule tasks- dispatch_queue
- Synchronize tasks- dispatch_group
- Serialize asynchronous tasks- dispatch_suspend and dispatch_resume
GCD Techniques
8
Scheduling Tasks with GCD
GCD - Scheduling Tasks with Queues
Queues
Serial
Concurrent
10
GCD - Scheduling Tasks with Queues
Queues
^{1}^{2}
^{1}^{2}^{3}
^{3}
11
dispatch_queue_t dispatch_queue_create(const char *label,dispatch_queue_attr_t attr
);
dispatch_queue_create(“q”, DISPATCH_QUEUE_SERIAL);dispatch_queue_create(“q”, DISPATCH_QUEUE_CONCURRENT);
GCD - Scheduling Tasks with Queues
12
Quality of Service Class
- Urgency of queued tasks- Relative priority
GCD - Scheduling Tasks with QueuesiOS 8+
QOS_CLASS_USER_INTERACTIVE
QOS_CLASS_USER_INITIATED
QOS_CLASS_DEFAULT
QOS_CLASS_UTILITY
QOS_CLASS_BACKGROUND
13
GCD - Scheduling Tasks with QueuesiOS 8+
QOS_CLASS_USER_INTERACTIVE
QOS_CLASS_USER_INITIATED
QOS_CLASS_DEFAULT
QOS_CLASS_UTILITY
QOS_CLASS_BACKGROUND
14
dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
QOS_CLASS_USER_INITIATED
QOS_CLASS_UTILITY
- 5 Global Queues- 1 per QOS class- Concurrent, background thread
GCD - Scheduling Tasks with Queues
dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);
15
Queues can target other queues- (a) dispatch_queue_create(“q”, DISPATCH_QUEUE_SERIAL);
GCD - Scheduling Tasks with Queues
^{2}^{3} ^{1}
(a)16
(b)
- (b) Global QOS_CLASS_DEFAULT
GCD - Scheduling Tasks with Queues
^{3} ^{2} ^{1}
dispatch_set_target_queue(someQ, targetQ);
(a) (b)
17
GCD - Scheduling Tasks with Queues
18
QOS_CLASS_UTILITY
QOS_CLASS_USER_INITIATED
GCD - Scheduling Tasks with Queues
Task- dispatch_block_t b = ^{};
Schedule a task in GCD- dispatch_sync(queue, ^{}) // Blocking- dispatch_async(queue, ^{}) // Non blocking
19
GCD - Scheduling Tasks with Queues
- Special 6th global queue - main queue- dispatch_get_main_queue()- Executes blocks on the main thread
20
GCD - Scheduling Tasks with Queues
Common Patterndispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT), ^{
// do some expensive workdispatch_async(dispatch_get_main_queue(), ^{
// show user the work i did});
});
21
DemoCat Pyramid
Synchronizing Tasks with GCD
GCD - Synchronizing Tasks
Problem - User generated video- 2 tasks:
- Crop video- Generate thumbnails for
keyframe slider
24
GCD - Synchronizing TasksPotential Solution - BOOL Flags
- isVideoProccessed- areSliderImagesGenerated
- (void)hideLoadingIfPossible {if (self.isVideoProcessed && self.areSliderImagesGenerated) { // Hide the loading spinner}
} 25
GCD - Synchronizing TasksPotential Solution - BOOL Flags- (void)hideLoadingIfPossible {
if (self.isVideoProcessed && self.areSliderImagesGenerated &&
self.isAudioProcessed && self.isUserReadyToSeeThis self.areYouSureUserIsReady) {
// Hide the loading spinner}
}26
Better Solution - Dispatch Groupsdispatch_group_t
- dispatch_group_create();
- Creates a new empty group
- dispatch_group_enter(group);
- Increments the number of tasks in group
- dispatch_group_leave(group);
- Decrements the number of tasks in group
GCD - Synchronizing Tasks
27
Potential solution - Dispatch Groupsdispatch_group_t group = dispatch_group_create();
// For each task:// call dispatch_group_enter(group) on start// call dispatch_group_leave on tasks completion
// Call wait to block until task count is 0dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
GCD - Synchronizing Tasks
28
Potential solution - Dispatch Groupsdispatch_group_t group = dispatch_group_create();
// For each task:// call dispatch_group_enter(group) on start// call dispatch_group_leave on tasks completiondispatch_async(someConcurrentQueue, ^{ // Call wait to block until task count is 0 dispatch_group_wait(group, DISPATCH_TIME_FOREVER);});
GCD - Synchronizing Tasks
29
GCD - Synchronizing Tasks
Optimal Solution- dispatch_group_notify(group, queue, block);
- Read “When there are no tasks left associated with this group, notify by
enqueueing this block onto this queue”
30
DemoCat Pyramid - Faster
Serialize Asynchronous Tasks
Sync Task- Easily fits into a block- Blocks until the task is done
Async Task- Task happens in another thread/process- Starting this task returns immediately
GCD - Serialize Async Tasks
33
Problem - Animations
GCD - Serialize Async Tasks
34
GCD - Serialize Async Tasks
Problem - Animations[UIView animateWithDuration:1.0 animations:^{
// Rotate 90 degrees} completion:^(BOOL finished) {
[UIView animateWithDuration:0.5 animations:^{ // Move down the screen 100pt } completion:NULL];}];
35
DemoFun with Animation Queueing
GCD - Caveats
Cleanup is hard
- if a dispatch_group_t is deallocated with a non-zero task count, it will throw an exception
- dispatch_async“…The queue is retained by the system until the block has run to completion…” - Apple Docs
37
Tools in the Toolbelt
GCD- Small synchronous tasks- Simple asynchronous tasks
NSOperation and NSOperationQueue- Complex asynchronous tasks- Cancel support
38
What else can I do with GCD?
- Efficient reader/writer schemes- dispatch_barrier
- Read and write data efficiently- dispatch_io (disk) and dispatch_data (memory)
- Respond to low-level system objects- dispatch_source
39
ResourcesGCD Source
- https://libdispatch.macosforge.org/trac/browser/trunk
GCD Documentation- https://developer.apple.
com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/
Demo App- https://github.com/benasher44/SGConf2015Demo
40