SlideShare a Scribd company logo
1 of 39
Grand Central Dispatch
Design Patterns
By Robert Brown
@robby_brown
Blocks
Blocks

Blocks are a proposed addition to C.
Like a function pointer, except it also stores the context
the block was created in.
Similar to closures, lambdas, and anonymous functions
in other languages.
Blocks
Declaration Syntax:
returnType (^blockName) (Arguments)
Blocks may be anonymous.
Definition Syntax:
^ returnType (Arguments) { code; }
The return type and arguments are optional.
GCD provides function pointer variants to the block APIs.
Blocks
Blocks can modify local variables outside of their scope
if the variables have the new __block keyword.
Global and static variables can be modified without the
__block keyword.
Blocks automatically retain Objective-C objects, except
objects that use the __block modifier.
C objects must be manually retained.
Beware of retain cycles.
Grand Central Dispatch
What is GCD?

GCD is a lightweight multithreading engine.
Uses a thread pool.
Developers create queues of blocks rather than
threads.
Uses lock-less exclusion rather than mutual exclusion.
Replaces blocking and polling APIs.
Why Multithread on a Single
Core?

Keeps the UI responsive.
UI code runs on the main thread.
Everything else runs on a background thread.
Prevents the main thread from blocking or waiting.
Frequently Used APIs
dispatch_async(queue, block);
dispatch_once(token, block);
dispatch_queue_create(name, type);
dispatch_set_target_queue(object, queue);
dispatch_get_global_queue(priority, flags);
dispatch_release(object);
Global Queues

Four global queues:
  Main, Low, Default, and High.
Only the main thread services the main queue.
The three other queues determine the priority of
background tasks.
Enqueuing is thread safe.
Design Patterns
What is a Design Pattern?


After working on related problems, patterns often
appear in the solutions.
Formalized description of best practice.
Initialization Pattern
dispatch_once

Guaranteed to run only once for the lifetime of the
application.
Fast and thread safe.
Very easy to use.
Great for singletons and static class variables.
The Old Way
static MyObject * myObject = nil;
+ myObject {
    @synchronized(self) {
        if (!myObject) myObject = [MyObject new];
    }
    return myObject;
}
Problems With
@synchronized
@synchronized is slow.
When synchronizing on the class instance, all
other methods that synchronize on it will
temporarily block incoming messages.
You can’t synchronize on the class variable since it
is initially nil.
Using a custom lock also faces the initialization
problem.
The GCD Way
static MyObject * myObject = nil;
+ myObject {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
          if (!myObject) myObject = [MyObject new];
    });
    return myObject;
}
Lockless Exclusion Pattern
Mutual Exclusion

Mutual exclusion is classically handled by semaphores
or locks.
Both are most efficient when there is no sharing
conflicts, (i.e. when you don’t need them) and don’t
scale well.
Queues are efficient and scale very well.
In fact, queues are most efficient under high conflict.
Thread-safe Access
// myQueue must be a serial queue      NSLock * lock = [NSLock new];



dispatch_async(myQueue, ^{             [lock lock];

      [self setMySharedVariable:42];   [self setMySharedVariable:42];

});                                    [lock unlock];
Enforcing Lockless
Exclusion

- (NSInteger)mySharedVariable {
     NSAssert(dispatch_get_current_queue() ==
     myQueue, @“Wrong queue.”);
     return mySharedVariable;
 }
Problems with Getters/
Setters

We would rather have the compiler write our getters/
setters.
  This technique works well in other methods.
Only immutable objects are fully protected this way.
Enforcing Lockless
Exclusion
- (void)accessSharedVariableAsync:(void(^)(id sharedVariable))block {

     // myQueue must be a serial queue!

     dispatch_async(myQueue, ^{

           block([self sharedVariable]);

     });

}
Enforcing Lockless
Exclusion
- (void)accessSharedVariableSyncSafe:(void(^)(id sharedVariable))block {
     // myQueue must be a serial queue!
     if (dispatch_get_current_queue() == myQueue)
        block([self sharedVariable]);
     else
        dispatch_sync(myQueue, ^{
              block([self sharedVariable]);
        });
}
Compare to
      @synchronized
[obj accessSharedDataAsync:^(id sharedVar)   @synchronized ([obj sharedVar])

{                                            {

      // Critical code here.                       // Critical code here.

}                                            }

    Fast - No Locks                              Slow - Recursive Lock

    Allows private access                        Must allow public access

    Synchronous or Asynchronous                  Synchronous Only

    Can be extended to access many shared        Only single-value access.
    data values at once.
Striding Pattern
Why Striding?

  Myth: My app will go faster if I multithread.
  Your app will only be faster if the work is
  parallelizable.
  Sometimes a block simply contains a loop, and
  each iteration can be run independently of the
  others.
  So, why not spread the iterations across many
  threads?
One Thread

dispatch_async(myQueue, ^{
      for(int i = 0; i < 10; i++)
        [self doIndependentTask:i];
});
dispatch_apply

// myQueue must be a concurrent queue!
dispatch_apply(10, myQueue, ^(size_t idx) {
      [self doIndependentTask:idx];
});
Problems with
dispatch_apply
One thread per iteration may be overkill and result in
high overhead costs.
Solution: Use striding (i.e. have one thread run many
iterations).
  Similar to loop unrolling.
  You may need to profile your app to find the ideal
  stride length.
size_t stride = 4;

size_t iterations = 10;

size_t strideCount = iterations / stride;

// myQueue must be a concurrent queue!

dispatch_apply(strideCount, myQueue, ^(size_t idx) {

       size_t i = idx * stride;

       size_t stop = i + stride;

       do {

              [self doIndependentTask:i++];

       } while (i < stop);

});

// Pick up any left over iterations.

for (size_t i = strideCount - (strideCount % stride); i < iterations; i++)

       [self doIndependentTask:i];
Continuation Pattern
What is a Continuation?


Well, it’s complicated...take CS 330.
Think of it like a completion block wrapped in a
completion block wrapped in a completion block...
Using Continuations
The following steps are optional, but either 4 or 5 must be
done.
 1. Do some processing.
 2. Wrap the completion block in another block.
 3. Copy the block if it is going to cross threads
    (unnecessary with ARC).
 4. Pass the completion block to someone else.
 5. Execute the completion block.
typedef void(^CHCompletion)(NSError * error);

- (void)uploadPhoto:(NSString *)photoPath {

     // Do some pre-processing.

     [self processPhotoAtPath:photoPath completion:^(NSError * error) {

           if (error)

               dispatch_async(dispatch_get_main_queue(), ^{

                     // Inform user of error

               });

     }];

}
- (void)processPhotoAtPath:(NSString *)path completion:
(CHCompletion)completion {

     [[completion copy] autorelease];

     // Do some resizing and add a caption, then save the modified photo
     to a temporary file for memory efficiency.

     [self uploadProcessedPhotoAtPath:newPath completion:^(NSError *
     error) {

           // Delete the temporary file.

           if (completion) completion(error);

     }];

}
- (void)uploadProcessedPhotoAtPath:(NSString *)path
completion:(CHCompletion)completion {

    [[completion copy] autorelease];

    NSError * error = nil;

    // Upload the photo.

    // Set error if something goes wrong.

    if (completion) completion(error);

}
Want to Learn More?
WWDC 2011
  Session 308
  Session 210
WWDC 2010
  Session 206
  Session 211
https://github.com/rob-brown/RBCategories/blob/master/
GCD+RBExtras.c
Questions?

More Related Content

What's hot

Grand Central Dispatch - iOS Conf SG 2015
Grand Central Dispatch - iOS Conf SG 2015Grand Central Dispatch - iOS Conf SG 2015
Grand Central Dispatch - iOS Conf SG 2015
Ben Asher
 
Java New Evolution
Java New EvolutionJava New Evolution
Java New Evolution
Allan Huang
 

What's hot (20)

Grand Central Dispatch - iOS Conf SG 2015
Grand Central Dispatch - iOS Conf SG 2015Grand Central Dispatch - iOS Conf SG 2015
Grand Central Dispatch - iOS Conf SG 2015
 
Threading in iOS / Cocoa Touch
Threading in iOS / Cocoa TouchThreading in iOS / Cocoa Touch
Threading in iOS / Cocoa Touch
 
Effective java - concurrency
Effective java - concurrencyEffective java - concurrency
Effective java - concurrency
 
Java Concurrency Gotchas
Java Concurrency GotchasJava Concurrency Gotchas
Java Concurrency Gotchas
 
Java Concurrency in Practice
Java Concurrency in PracticeJava Concurrency in Practice
Java Concurrency in Practice
 
Java New Evolution
Java New EvolutionJava New Evolution
Java New Evolution
 
Concurrency in Java
Concurrency in  JavaConcurrency in  Java
Concurrency in Java
 
Objective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central DispatchObjective-C Blocks and Grand Central Dispatch
Objective-C Blocks and Grand Central Dispatch
 
Java Concurrency Idioms
Java Concurrency IdiomsJava Concurrency Idioms
Java Concurrency Idioms
 
Stoop 305-reflective programming5
Stoop 305-reflective programming5Stoop 305-reflective programming5
Stoop 305-reflective programming5
 
Node.js Workshop - Sela SDP 2015
Node.js Workshop  - Sela SDP 2015Node.js Workshop  - Sela SDP 2015
Node.js Workshop - Sela SDP 2015
 
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
Concurrency Programming in Java - 07 - High-level Concurrency objects, Lock O...
 
The Java memory model made easy
The Java memory model made easyThe Java memory model made easy
The Java memory model made easy
 
Basics of Java Concurrency
Basics of Java ConcurrencyBasics of Java Concurrency
Basics of Java Concurrency
 
Multithreading on iOS
Multithreading on iOSMultithreading on iOS
Multithreading on iOS
 
How to Test Asynchronous Code (v2)
How to Test Asynchronous Code (v2)How to Test Asynchronous Code (v2)
How to Test Asynchronous Code (v2)
 
Why GC is eating all my CPU?
Why GC is eating all my CPU?Why GC is eating all my CPU?
Why GC is eating all my CPU?
 
Realm.io par Clement Sauvage
Realm.io par Clement SauvageRealm.io par Clement Sauvage
Realm.io par Clement Sauvage
 
Behavioral Reflection
Behavioral ReflectionBehavioral Reflection
Behavioral Reflection
 
Java Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and TrendsJava Concurrency, Memory Model, and Trends
Java Concurrency, Memory Model, and Trends
 

Viewers also liked

Lecture 3 and 4 threads
Lecture 3 and 4  threadsLecture 3 and 4  threads
Lecture 3 and 4 threads
Rushdi Shams
 
Presentation final
Presentation finalPresentation final
Presentation final
iteclearners
 
History of the Corset
History of the CorsetHistory of the Corset
History of the Corset
mwett001
 
Multithreading In Java
Multithreading In JavaMultithreading In Java
Multithreading In Java
parag
 
Fashion through the decades
Fashion through the decadesFashion through the decades
Fashion through the decades
marifex88
 
Baroque n rococo
Baroque n rococoBaroque n rococo
Baroque n rococo
AppyRocks
 

Viewers also liked (20)

Lecture 3 and 4 threads
Lecture 3 and 4  threadsLecture 3 and 4  threads
Lecture 3 and 4 threads
 
Programação Assíncrona com C# 5
Programação Assíncrona com C# 5Programação Assíncrona com C# 5
Programação Assíncrona com C# 5
 
Edição mercado livre2
Edição mercado livre2Edição mercado livre2
Edição mercado livre2
 
TDC 2012 Goiânia: Trilha .NET - Novidades do .NET Framework 4.5
TDC 2012 Goiânia: Trilha .NET - Novidades do .NET Framework 4.5TDC 2012 Goiânia: Trilha .NET - Novidades do .NET Framework 4.5
TDC 2012 Goiânia: Trilha .NET - Novidades do .NET Framework 4.5
 
IAsyncResult Pattern ou Asynchronous Programming Model (APM)
IAsyncResult Pattern ou Asynchronous Programming Model (APM)IAsyncResult Pattern ou Asynchronous Programming Model (APM)
IAsyncResult Pattern ou Asynchronous Programming Model (APM)
 
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
Programação assíncrona com C# 5 no Visual Studio 2013 [MVP ShowCast 2013 - DE...
 
Presentation final
Presentation finalPresentation final
Presentation final
 
Corsets
CorsetsCorsets
Corsets
 
History of corsets
History of corsetsHistory of corsets
History of corsets
 
History of the Corset
History of the CorsetHistory of the Corset
History of the Corset
 
Rococo art
Rococo artRococo art
Rococo art
 
Multithread Programing in Java
Multithread Programing in JavaMultithread Programing in Java
Multithread Programing in Java
 
Multithreading In Java
Multithreading In JavaMultithreading In Java
Multithreading In Java
 
Programação assíncrona com C#
Programação assíncrona com C#Programação assíncrona com C#
Programação assíncrona com C#
 
Baroque and rococo architecture
Baroque and rococo architectureBaroque and rococo architecture
Baroque and rococo architecture
 
Rococo
RococoRococo
Rococo
 
Fashion through the decades
Fashion through the decadesFashion through the decades
Fashion through the decades
 
Rococo art and architecture
Rococo art and architectureRococo art and architecture
Rococo art and architecture
 
Baroque n rococo
Baroque n rococoBaroque n rococo
Baroque n rococo
 
Fashion History
Fashion HistoryFashion History
Fashion History
 

Similar to Grand Central Dispatch Design Patterns

Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
Sri Prasanna
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java Developers
Muhammad Abdullah
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
priyank09
 

Similar to Grand Central Dispatch Design Patterns (20)

JAVA CONCEPTS AND PRACTICES
JAVA CONCEPTS AND PRACTICESJAVA CONCEPTS AND PRACTICES
JAVA CONCEPTS AND PRACTICES
 
Jist of Java
Jist of JavaJist of Java
Jist of Java
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
04 threads
04 threads04 threads
04 threads
 
Swift - One step forward from Obj-C
Swift -  One step forward from Obj-CSwift -  One step forward from Obj-C
Swift - One step forward from Obj-C
 
Threaded Programming
Threaded ProgrammingThreaded Programming
Threaded Programming
 
Objective-C Is Not Java
Objective-C Is Not JavaObjective-C Is Not Java
Objective-C Is Not Java
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
How AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design PatternsHow AngularJS Embraced Traditional Design Patterns
How AngularJS Embraced Traditional Design Patterns
 
React native
React nativeReact native
React native
 
Structural pattern 3
Structural pattern 3Structural pattern 3
Structural pattern 3
 
Objective-c for Java Developers
Objective-c for Java DevelopersObjective-c for Java Developers
Objective-c for Java Developers
 
Group111
Group111Group111
Group111
 
Java tut1
Java tut1Java tut1
Java tut1
 
Tutorial java
Tutorial javaTutorial java
Tutorial java
 
Java Tut1
Java Tut1Java Tut1
Java Tut1
 
Java Tutorial
Java TutorialJava Tutorial
Java Tutorial
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
 
Best practices in Java
Best practices in JavaBest practices in Java
Best practices in Java
 

More from Robert Brown

More from Robert Brown (13)

High level concurrency
High level concurrencyHigh level concurrency
High level concurrency
 
Data Source Combinators
Data Source CombinatorsData Source Combinators
Data Source Combinators
 
Elixir
ElixirElixir
Elixir
 
MVVM
MVVMMVVM
MVVM
 
Reactive Cocoa
Reactive CocoaReactive Cocoa
Reactive Cocoa
 
UIKit Dynamics
UIKit DynamicsUIKit Dynamics
UIKit Dynamics
 
iOS State Preservation and Restoration
iOS State Preservation and RestorationiOS State Preservation and Restoration
iOS State Preservation and Restoration
 
Anti-Patterns
Anti-PatternsAnti-Patterns
Anti-Patterns
 
Pragmatic blocks
Pragmatic blocksPragmatic blocks
Pragmatic blocks
 
Grand Central Dispatch
Grand Central DispatchGrand Central Dispatch
Grand Central Dispatch
 
Mac/iOS Design Patterns
Mac/iOS Design PatternsMac/iOS Design Patterns
Mac/iOS Design Patterns
 
Core Data
Core DataCore Data
Core Data
 
Quick Look for iOS
Quick Look for iOSQuick Look for iOS
Quick Look for iOS
 

Recently uploaded

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

Grand Central Dispatch Design Patterns

  • 1. Grand Central Dispatch Design Patterns By Robert Brown @robby_brown
  • 3. Blocks Blocks are a proposed addition to C. Like a function pointer, except it also stores the context the block was created in. Similar to closures, lambdas, and anonymous functions in other languages.
  • 4. Blocks Declaration Syntax: returnType (^blockName) (Arguments) Blocks may be anonymous. Definition Syntax: ^ returnType (Arguments) { code; } The return type and arguments are optional. GCD provides function pointer variants to the block APIs.
  • 5. Blocks Blocks can modify local variables outside of their scope if the variables have the new __block keyword. Global and static variables can be modified without the __block keyword. Blocks automatically retain Objective-C objects, except objects that use the __block modifier. C objects must be manually retained. Beware of retain cycles.
  • 7. What is GCD? GCD is a lightweight multithreading engine. Uses a thread pool. Developers create queues of blocks rather than threads. Uses lock-less exclusion rather than mutual exclusion. Replaces blocking and polling APIs.
  • 8. Why Multithread on a Single Core? Keeps the UI responsive. UI code runs on the main thread. Everything else runs on a background thread. Prevents the main thread from blocking or waiting.
  • 9. Frequently Used APIs dispatch_async(queue, block); dispatch_once(token, block); dispatch_queue_create(name, type); dispatch_set_target_queue(object, queue); dispatch_get_global_queue(priority, flags); dispatch_release(object);
  • 10. Global Queues Four global queues: Main, Low, Default, and High. Only the main thread services the main queue. The three other queues determine the priority of background tasks. Enqueuing is thread safe.
  • 12. What is a Design Pattern? After working on related problems, patterns often appear in the solutions. Formalized description of best practice.
  • 14. dispatch_once Guaranteed to run only once for the lifetime of the application. Fast and thread safe. Very easy to use. Great for singletons and static class variables.
  • 15. The Old Way static MyObject * myObject = nil; + myObject { @synchronized(self) { if (!myObject) myObject = [MyObject new]; } return myObject; }
  • 16. Problems With @synchronized @synchronized is slow. When synchronizing on the class instance, all other methods that synchronize on it will temporarily block incoming messages. You can’t synchronize on the class variable since it is initially nil. Using a custom lock also faces the initialization problem.
  • 17. The GCD Way static MyObject * myObject = nil; + myObject { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ if (!myObject) myObject = [MyObject new]; }); return myObject; }
  • 19. Mutual Exclusion Mutual exclusion is classically handled by semaphores or locks. Both are most efficient when there is no sharing conflicts, (i.e. when you don’t need them) and don’t scale well. Queues are efficient and scale very well. In fact, queues are most efficient under high conflict.
  • 20. Thread-safe Access // myQueue must be a serial queue NSLock * lock = [NSLock new]; dispatch_async(myQueue, ^{ [lock lock]; [self setMySharedVariable:42]; [self setMySharedVariable:42]; }); [lock unlock];
  • 21. Enforcing Lockless Exclusion - (NSInteger)mySharedVariable { NSAssert(dispatch_get_current_queue() == myQueue, @“Wrong queue.”); return mySharedVariable; }
  • 22. Problems with Getters/ Setters We would rather have the compiler write our getters/ setters. This technique works well in other methods. Only immutable objects are fully protected this way.
  • 23. Enforcing Lockless Exclusion - (void)accessSharedVariableAsync:(void(^)(id sharedVariable))block { // myQueue must be a serial queue! dispatch_async(myQueue, ^{ block([self sharedVariable]); }); }
  • 24. Enforcing Lockless Exclusion - (void)accessSharedVariableSyncSafe:(void(^)(id sharedVariable))block { // myQueue must be a serial queue! if (dispatch_get_current_queue() == myQueue) block([self sharedVariable]); else dispatch_sync(myQueue, ^{ block([self sharedVariable]); }); }
  • 25. Compare to @synchronized [obj accessSharedDataAsync:^(id sharedVar) @synchronized ([obj sharedVar]) { { // Critical code here. // Critical code here. } } Fast - No Locks Slow - Recursive Lock Allows private access Must allow public access Synchronous or Asynchronous Synchronous Only Can be extended to access many shared Only single-value access. data values at once.
  • 27. Why Striding? Myth: My app will go faster if I multithread. Your app will only be faster if the work is parallelizable. Sometimes a block simply contains a loop, and each iteration can be run independently of the others. So, why not spread the iterations across many threads?
  • 28. One Thread dispatch_async(myQueue, ^{ for(int i = 0; i < 10; i++) [self doIndependentTask:i]; });
  • 29. dispatch_apply // myQueue must be a concurrent queue! dispatch_apply(10, myQueue, ^(size_t idx) { [self doIndependentTask:idx]; });
  • 30. Problems with dispatch_apply One thread per iteration may be overkill and result in high overhead costs. Solution: Use striding (i.e. have one thread run many iterations). Similar to loop unrolling. You may need to profile your app to find the ideal stride length.
  • 31. size_t stride = 4; size_t iterations = 10; size_t strideCount = iterations / stride; // myQueue must be a concurrent queue! dispatch_apply(strideCount, myQueue, ^(size_t idx) { size_t i = idx * stride; size_t stop = i + stride; do { [self doIndependentTask:i++]; } while (i < stop); }); // Pick up any left over iterations. for (size_t i = strideCount - (strideCount % stride); i < iterations; i++) [self doIndependentTask:i];
  • 33. What is a Continuation? Well, it’s complicated...take CS 330. Think of it like a completion block wrapped in a completion block wrapped in a completion block...
  • 34. Using Continuations The following steps are optional, but either 4 or 5 must be done. 1. Do some processing. 2. Wrap the completion block in another block. 3. Copy the block if it is going to cross threads (unnecessary with ARC). 4. Pass the completion block to someone else. 5. Execute the completion block.
  • 35. typedef void(^CHCompletion)(NSError * error); - (void)uploadPhoto:(NSString *)photoPath { // Do some pre-processing. [self processPhotoAtPath:photoPath completion:^(NSError * error) { if (error) dispatch_async(dispatch_get_main_queue(), ^{ // Inform user of error }); }]; }
  • 36. - (void)processPhotoAtPath:(NSString *)path completion: (CHCompletion)completion { [[completion copy] autorelease]; // Do some resizing and add a caption, then save the modified photo to a temporary file for memory efficiency. [self uploadProcessedPhotoAtPath:newPath completion:^(NSError * error) { // Delete the temporary file. if (completion) completion(error); }]; }
  • 37. - (void)uploadProcessedPhotoAtPath:(NSString *)path completion:(CHCompletion)completion { [[completion copy] autorelease]; NSError * error = nil; // Upload the photo. // Set error if something goes wrong. if (completion) completion(error); }
  • 38. Want to Learn More? WWDC 2011 Session 308 Session 210 WWDC 2010 Session 206 Session 211 https://github.com/rob-brown/RBCategories/blob/master/ GCD+RBExtras.c

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n