40
Grand Central Dispatch Ben Asher [email protected] benasher44 on Github and Twitter

Grand Central Dispatch - iOS Conf SG 2015

Embed Size (px)

Citation preview

Page 1: Grand Central Dispatch - iOS Conf SG 2015

Grand Central DispatchBen Asher

[email protected] on Github and Twitter

Page 2: Grand Central Dispatch - iOS Conf SG 2015

Yelp’s Mission:Connecting people with great

local businesses.

2

Page 3: Grand Central Dispatch - iOS Conf SG 2015

Yelp Stats:As of Q2 2015

83M 3268%83M

3

Page 4: Grand Central Dispatch - iOS Conf SG 2015

A Responsive App

- Responsive UI

- Don’t make the user wait

4

Page 5: Grand Central Dispatch - iOS Conf SG 2015

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

};

Page 6: Grand Central Dispatch - iOS Conf SG 2015

What is GCD about?

“…technology that you use to manage the execution of tasks in your app…”

- Apple Docs

6

Page 7: Grand Central Dispatch - iOS Conf SG 2015

- C API (mostly)

- Open source!

- Task = ^{}

GCD - Intro

7

Page 8: Grand Central Dispatch - iOS Conf SG 2015

- Schedule tasks- dispatch_queue

- Synchronize tasks- dispatch_group

- Serialize asynchronous tasks- dispatch_suspend and dispatch_resume

GCD Techniques

8

Page 9: Grand Central Dispatch - iOS Conf SG 2015

Scheduling Tasks with GCD

Page 10: Grand Central Dispatch - iOS Conf SG 2015

GCD - Scheduling Tasks with Queues

Queues

Serial

Concurrent

10

Page 11: Grand Central Dispatch - iOS Conf SG 2015

GCD - Scheduling Tasks with Queues

Queues

^{1}^{2}

^{1}^{2}^{3}

^{3}

11

Page 12: Grand Central Dispatch - iOS Conf SG 2015

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

Page 13: Grand Central Dispatch - iOS Conf SG 2015

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

Page 14: Grand Central Dispatch - iOS Conf SG 2015

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

Page 15: Grand Central Dispatch - iOS Conf SG 2015

- 5 Global Queues- 1 per QOS class- Concurrent, background thread

GCD - Scheduling Tasks with Queues

dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

15

Page 16: Grand Central Dispatch - iOS Conf SG 2015

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

Page 17: Grand Central Dispatch - iOS Conf SG 2015

GCD - Scheduling Tasks with Queues

^{3} ^{2} ^{1}

dispatch_set_target_queue(someQ, targetQ);

(a) (b)

17

Page 18: Grand Central Dispatch - iOS Conf SG 2015

GCD - Scheduling Tasks with Queues

18

QOS_CLASS_UTILITY

QOS_CLASS_USER_INITIATED

Page 19: Grand Central Dispatch - iOS Conf SG 2015

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

Page 20: Grand Central Dispatch - iOS Conf SG 2015

GCD - Scheduling Tasks with Queues

- Special 6th global queue - main queue- dispatch_get_main_queue()- Executes blocks on the main thread

20

Page 21: Grand Central Dispatch - iOS Conf SG 2015

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

Page 22: Grand Central Dispatch - iOS Conf SG 2015

DemoCat Pyramid

Page 23: Grand Central Dispatch - iOS Conf SG 2015

Synchronizing Tasks with GCD

Page 24: Grand Central Dispatch - iOS Conf SG 2015

GCD - Synchronizing Tasks

Problem - User generated video- 2 tasks:

- Crop video- Generate thumbnails for

keyframe slider

24

Page 25: Grand Central Dispatch - iOS Conf SG 2015

GCD - Synchronizing TasksPotential Solution - BOOL Flags

- isVideoProccessed- areSliderImagesGenerated

- (void)hideLoadingIfPossible {if (self.isVideoProcessed && self.areSliderImagesGenerated) { // Hide the loading spinner}

} 25

Page 26: Grand Central Dispatch - iOS Conf SG 2015

GCD - Synchronizing TasksPotential Solution - BOOL Flags- (void)hideLoadingIfPossible {

if (self.isVideoProcessed && self.areSliderImagesGenerated &&

self.isAudioProcessed && self.isUserReadyToSeeThis self.areYouSureUserIsReady) {

// Hide the loading spinner}

}26

Page 27: Grand Central Dispatch - iOS Conf SG 2015

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

Page 28: Grand Central Dispatch - iOS Conf SG 2015

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

Page 29: Grand Central Dispatch - iOS Conf SG 2015

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

Page 30: Grand Central Dispatch - iOS Conf SG 2015

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

Page 31: Grand Central Dispatch - iOS Conf SG 2015

DemoCat Pyramid - Faster

Page 32: Grand Central Dispatch - iOS Conf SG 2015

Serialize Asynchronous Tasks

Page 33: Grand Central Dispatch - iOS Conf SG 2015

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

Page 34: Grand Central Dispatch - iOS Conf SG 2015

Problem - Animations

GCD - Serialize Async Tasks

34

Page 35: Grand Central Dispatch - iOS Conf SG 2015

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

Page 36: Grand Central Dispatch - iOS Conf SG 2015

DemoFun with Animation Queueing

Page 37: Grand Central Dispatch - iOS Conf SG 2015

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

Page 38: Grand Central Dispatch - iOS Conf SG 2015

Tools in the Toolbelt

GCD- Small synchronous tasks- Simple asynchronous tasks

NSOperation and NSOperationQueue- Complex asynchronous tasks- Cancel support

38

Page 39: Grand Central Dispatch - iOS Conf SG 2015

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