SlideShare a Scribd company logo
1 of 78
Pragmatic Blocks
by Robert Brown
@robby_brown
Objectives


Introduce the concepts behind blocks
Touch lightly on Objective-C syntax
Focus on practical applications of blocks
Introduction
What are blocks?

Pieces of code that can be stored and executed when
needed
Also known as lambdas, closures, anonymous
functions, first-class functions, higher-order functions
Can be passed as a parameter, returned from a
method/function, and stored in data structures
Blocks make adding new features to a language easy
What does “closure” mean?

Blocks store all the variables that are in scope when the
block is created
Closure makes it possible to store a block indefinitely,
then restore the context at will
Objective-C objects are automatically retained/released
C objects must be manually retained/released
Block Syntax

Declaration Syntax:
returnType (^blockName) (Arguments)
Definition Syntax:
^ returnType (Arguments) { code; }
The return type and arguments are optional.
Block Syntax

Example:
    returnType (^block)(args) = ^(args) { ... };
Block types are ugly, use typedef:
    typedef returnType (^MyBlock)(args);
    MyBlock block = ^(args) { ... };
Gotchas
Retain loops
  Xcode profiler will warn you of block retain loops
Unlike regular Objective-C objects, blocks are created
on the stack
  Be sure to call -copy if you need it to live beyond the
  current stack frame
  Make sure to de-stackify blocks before storing them
  in a data structure
Application
What are blocks good for?

Completion callbacks
Continuations
Multithreading
Delegate replacement
Other design pattern modifications
Callbacks


Most uses of blocks are some form of callback
Since blocks have closure, they can restore the caller’s
context without any effort on our part
Completion Blocks

Most common use of blocks in Objective-C
A callback that happens only after some task has
finished
  Some operations, such as network requests take an
  unknown amount of time
  Core Animation also uses many completion blocks
Completion Blocks


           Object        Object
             A             B



           Block


   Object B finishes executing and calls
       Object A calls Object B and
       passescompletion block.
          the a completion block.
Completion Blocks


           Object        Object
             A             B



                         Block


   Object B finishes executing and calls
       Object A calls Object B and
       passescompletion block.
          the a completion block.
Completion Blocks


           Object        Object
             A             B



                         Block


   Object B finishes executing and calls
       Object A calls Object B and
       passescompletion block.
          the a completion block.
Continuations


Think of it like a completion block wrapped in a
completion block wrapped in a completion block...
Essentially building your own runtime stack.
Continuations


    Object        Object       Object
      A             B            C



     Block


   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Continuations


    Object        Object       Object
      A             B            C



                  Block


   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Continuations


    Object        Object       Object
      A             B            C



                  Block


   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Continuations


    Object        Object       Object
      A             B            C



                   Block




   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Continuations


    Object        Object       Object
      A             B            C



                                Block




   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Continuations


    Object        Object       Object
      A             B            C



                                Block




   Object C BAthen calls Objectand to
    Object finisheswraps Object A’s
     Object A calls Object needwith
     So, Object B Object B B and calls
       Object and executing C
    block theacompletion C finishes.
      knownew completion block.
       passes new completion block.
       theinwhen Object block.
               a completion block.
Multithreading: GCD

Grand Central Dispatch (GCD) makes heavy use of
blocks
Blocks are not tied to a thread until they are executed
Blocks can be queued up without blocking threads
Threads can spend more time running and less time
waiting
Multithreading: GCD



Code can be made asynchronous simply by
surrounding it with dispatch_async(queue, ^{ ... });
Multithreading: GCD
Thread Pool                      Concurrent Queue
                    Block
   Thread             C
                      D
                      B
                      A
     3
              2-Core Processor
   Thread
     2


   Thread
     1
Multithreading: GCD
Thread Pool                      Concurrent Queue
                    Block
   Thread             C
                      D
     3
              2-Core Processor
   Thread
     2                                 Block
                                         B

   Thread                              Block
     1                                   A
Multithreading: GCD
Thread Pool                      Concurrent Queue
                    Block
                      C
                      D

              2-Core Processor
   Thread        Thread Block
     3             1      A


   Thread                              Block
     2                                   B
Multithreading: GCD
Thread Pool                      Concurrent Queue
                    Block
                      C
                      D

              2-Core Processor
                 Thread Block
                   1      A


   Thread        Thread Block
     3             2      B
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
                 Thread Block
                   1      A            Block
                                         D
   Thread        Thread Block          Block
     3             2      B              C
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
   Thread        Thread Block
     2             1      A            Block
                                         D
   Thread              Block           Block
     3                   B               C
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
                 Thread Block
                   1      A


   Thread        Thread Block
                                       Block
     2             3      C
                          B              D
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
   Thread              Block
     1                   A


   Thread        Thread Block
                                       Block
     2             3      C
                          B              D
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
                 Thread Block
                   2      A
                          D


   Thread        Thread Block
     1             3      C
                          B
Multithreading: GCD
Thread Pool                      Concurrent Queue



              2-Core Processor
   Thread        Thread Block
     3             2      A
                          D


   Thread              Block
     1                   C
                         B
Multithreading: GCD
Thread Pool                      Concurrent Queue

   Thread
     2
              2-Core Processor
   Thread              Block
     3                   A
                         D


   Thread             Block
     1                  C
                        B
Block Delegation

Delegates are essentially protocols that specify a list of
method callbacks
These method callbacks can be easily replaced with
block callbacks
Rule of thumb: 3 or less delegate callbacks should be
handled using blocks.
Block Delegation

Advantages:
  No additional protocols
  No need to conform to a protocol
  Easy to change block callbacks dynamically
Block Delegation


Disadvantages:
  May not be appropriate when more than 3 callbacks
  are needed
Other Design Patterns
Template Method


Sometimes algorithms differ by only a few lines
Those few lines can be replaced by a virtual method
Subclasses define the virtual method
Template Method

Let’s use blocks instead!
Advantages:
  No need for subclassing
  May not need a new class at all
  Template can be changed dynamically
Template Method

- (void)doSomethingUsingBlock:(dispatch_block_t)block {
    // Do something
    block();
    // Do some more stuff
}
Example Templates
Debug Mode
+ (void)whileInDebug:(MyBlock)block {
#if defined(DEBUG)
    NSParameterAssert(block);
    block();
#endif
}
Lock Handling

// Python convenient lock handler
with myLock:
    // Do something
    // Can’t forget to lock/unlock
Lock Handling

+ (void)withLock:(NSLock)lock executeBlock:(MyBlock)block {
     NSParameterAssert(lock && block);
     [lock lock];
     block();
     [lock unlock];
 }
Builder Pattern


 Some objects have complex structures that vary widely
 between uses
   Examples: Database tables, UITableView
 A block can define the construction of an object
Builder Pattern
 // Ruby on Rails database table construction
 create_table :person do |t|
   t.string :name, null: false
   t.integer :age, null: false
   t.float :weight
 end
Builder Pattern
// Contrived example, but very feasible.
// Creating a custom table view form.
[RBTableView tableViewUsingBlock:^(RBTableView * t) {
      [t addStringField:@“name” required:YES];
      [t addIntegerField:@“age” required:YES];
      [t addFloatField:@“weight” required:NO];
}];
Lockless Exclusion
Accessor

Thread-sensitive code is called critical code
GCD allows for lockless-exclusion
  Lockless code is faster than lock code
Lockless Exclusion
Accessor

Multi-threading challenges:
  Multi-threaded code must be properly synchronized
  It’s easy to forget to add thread-safety code
Lockless Exclusion
Accessor

Solution:
  Have another object handle thread-safety
  Put critical code in a block
  Give the block to the thread-safety handler
Lockless Exclusion
Accessor
- (void)accessSharedDataAsync:(void(^)(id sharedData))block {

     NSParameterAssert(block);

     // myQueue must be a serial queue!

     dispatch_async(myQueue, ^{

           block([self sharedData]);

     });

}
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue


                                      Block




                                LEA
                                        C
                                        B
                                        A
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue

                        Block
                          C




                                LEA
                        Block
                          B

                        Block
                          A
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block                  Block
   A                      C

                        Block
                          B
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block                  Block
   A                      C

                        Block
                          B
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block
   A
   B

                        Block
                          C
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block
   A
   B

                        Block
                          C
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block
   C
   A
   B
Lockless Exclusion
Accessor
         Shared Data   Serial
Shared
 Data
          Manager      Queue




                                LEA
 Block
   C
   A
   B
Read/Write LEA

Code that only reads from shared memory doesn’t
need exclusive access
Code that writes to shared memory needs exclusive
access
GCD barrier blocks and concurrent queues are a
perfect solution
Read/Write LEA
// Read-only LEA

- (void)accessSharedDataReadOnlyAsync:(void(^)(id sharedData))block {

     NSParameterAssert(block);

     // myQueue must be a concurrent queue!

     dispatch_async([self myQueue], ^{

           block([self sharedData]);

     });

}
Read/Write LEA
// Read/write LEA

- (void)accessSharedDataReadWriteAsync:(void(^)(id sharedData))block {

     NSParameterAssert(block);

     // myQueue must be a concurrent queue!

     dispatch_barrier_async([self myQueue], ^{

           block([self sharedData]);

     });

}
Read/Write LEA

// All-in-one R/W-LEA
- (void)accessSharedDataAsyncReadOnly:(BOOL)readOnly withBlock:(void(^)(id
sharedData))block {
     if (readOnly)
        dispatch_async([self myQueue], ^{ block([self sharedData]); });
     else
        dispatch_barrier_async([self myQueue], ^{ block([self sharedData]); });
}
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
                                            Read
                                            Write
                                            Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue

                        Write




                                  R/W-LEA
                        Block
                                            Read
                                            Block
                        Read
                        Block

                        Read
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
                                            Read
                                            Block
 Read     Read
 Block    Block

                        Write
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue

                        Read




                                  R/W-LEA
                        Block

 Read     Read          Read
 Block    Block         Block

                        Write
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue

                        Read




                                  R/W-LEA
                        Block

 Read     Read          Read
 Block    Block         Block

                        Write
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue

                        Read




                                  R/W-LEA
                        Block

 Read     Read          Read
 Block    Block         Block

                        Write
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
 Write
 Read     Read          Read
 Block    Block         Block

                        Read
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
 Write
 Read     Read          Read
 Block    Block         Block

                        Read
                        Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
 Write
 Read     Read
 Block    Block
Read/Write LEA
         Shared Data Concurrent
Shared
 Data
          Manager     Queue




                                  R/W-LEA
 Write
 Read     Read
 Block    Block
Homework


I have only touched the surface of what blocks can do
Explore and find other design patterns you can convert
to use blocks
Want to Learn More?
Blocks are best learned by playing with them
Learn Ruby
  “The Pickaxe”
Learn Racket
10 Uses for Blocks
My Blog
Questions?

More Related Content

More from Robert Brown

Data Source Combinators
Data Source CombinatorsData Source Combinators
Data Source CombinatorsRobert Brown
 
iOS State Preservation and Restoration
iOS State Preservation and RestorationiOS State Preservation and Restoration
iOS State Preservation and RestorationRobert Brown
 
Automatic Reference Counting
Automatic Reference CountingAutomatic Reference Counting
Automatic Reference CountingRobert Brown
 
Grand Central Dispatch Design Patterns
Grand Central Dispatch Design PatternsGrand Central Dispatch Design Patterns
Grand Central Dispatch Design PatternsRobert Brown
 
Grand Central Dispatch
Grand Central DispatchGrand Central Dispatch
Grand Central DispatchRobert Brown
 
Mac/iOS Design Patterns
Mac/iOS Design PatternsMac/iOS Design Patterns
Mac/iOS Design PatternsRobert Brown
 
Quick Look for iOS
Quick Look for iOSQuick Look for iOS
Quick Look for iOSRobert Brown
 

More from Robert Brown (13)

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
 
Automatic Reference Counting
Automatic Reference CountingAutomatic Reference Counting
Automatic Reference Counting
 
Grand Central Dispatch Design Patterns
Grand Central Dispatch Design PatternsGrand Central Dispatch Design Patterns
Grand Central Dispatch Design Patterns
 
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

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 organizationRadu Cotescu
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
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 interpreternaman860154
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
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 Scriptwesley chun
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
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.pdfUK Journal
 
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 2024Rafal Los
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
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...Neo4j
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 

Recently uploaded (20)

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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
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
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
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...
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 

Pragmatic blocks

  • 1. Pragmatic Blocks by Robert Brown @robby_brown
  • 2. Objectives Introduce the concepts behind blocks Touch lightly on Objective-C syntax Focus on practical applications of blocks
  • 4. What are blocks? Pieces of code that can be stored and executed when needed Also known as lambdas, closures, anonymous functions, first-class functions, higher-order functions Can be passed as a parameter, returned from a method/function, and stored in data structures Blocks make adding new features to a language easy
  • 5. What does “closure” mean? Blocks store all the variables that are in scope when the block is created Closure makes it possible to store a block indefinitely, then restore the context at will Objective-C objects are automatically retained/released C objects must be manually retained/released
  • 6. Block Syntax Declaration Syntax: returnType (^blockName) (Arguments) Definition Syntax: ^ returnType (Arguments) { code; } The return type and arguments are optional.
  • 7. Block Syntax Example: returnType (^block)(args) = ^(args) { ... }; Block types are ugly, use typedef: typedef returnType (^MyBlock)(args); MyBlock block = ^(args) { ... };
  • 8. Gotchas Retain loops Xcode profiler will warn you of block retain loops Unlike regular Objective-C objects, blocks are created on the stack Be sure to call -copy if you need it to live beyond the current stack frame Make sure to de-stackify blocks before storing them in a data structure
  • 10. What are blocks good for? Completion callbacks Continuations Multithreading Delegate replacement Other design pattern modifications
  • 11. Callbacks Most uses of blocks are some form of callback Since blocks have closure, they can restore the caller’s context without any effort on our part
  • 12. Completion Blocks Most common use of blocks in Objective-C A callback that happens only after some task has finished Some operations, such as network requests take an unknown amount of time Core Animation also uses many completion blocks
  • 13. Completion Blocks Object Object A B Block Object B finishes executing and calls Object A calls Object B and passescompletion block. the a completion block.
  • 14. Completion Blocks Object Object A B Block Object B finishes executing and calls Object A calls Object B and passescompletion block. the a completion block.
  • 15. Completion Blocks Object Object A B Block Object B finishes executing and calls Object A calls Object B and passescompletion block. the a completion block.
  • 16. Continuations Think of it like a completion block wrapped in a completion block wrapped in a completion block... Essentially building your own runtime stack.
  • 17. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 18. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 19. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 20. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 21. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 22. Continuations Object Object Object A B C Block Object C BAthen calls Objectand to Object finisheswraps Object A’s Object A calls Object needwith So, Object B Object B B and calls Object and executing C block theacompletion C finishes. knownew completion block. passes new completion block. theinwhen Object block. a completion block.
  • 23. Multithreading: GCD Grand Central Dispatch (GCD) makes heavy use of blocks Blocks are not tied to a thread until they are executed Blocks can be queued up without blocking threads Threads can spend more time running and less time waiting
  • 24. Multithreading: GCD Code can be made asynchronous simply by surrounding it with dispatch_async(queue, ^{ ... });
  • 25. Multithreading: GCD Thread Pool Concurrent Queue Block Thread C D B A 3 2-Core Processor Thread 2 Thread 1
  • 26. Multithreading: GCD Thread Pool Concurrent Queue Block Thread C D 3 2-Core Processor Thread 2 Block B Thread Block 1 A
  • 27. Multithreading: GCD Thread Pool Concurrent Queue Block C D 2-Core Processor Thread Thread Block 3 1 A Thread Block 2 B
  • 28. Multithreading: GCD Thread Pool Concurrent Queue Block C D 2-Core Processor Thread Block 1 A Thread Thread Block 3 2 B
  • 29. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Block 1 A Block D Thread Thread Block Block 3 2 B C
  • 30. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Thread Block 2 1 A Block D Thread Block Block 3 B C
  • 31. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Block 1 A Thread Thread Block Block 2 3 C B D
  • 32. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Block 1 A Thread Thread Block Block 2 3 C B D
  • 33. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Block 2 A D Thread Thread Block 1 3 C B
  • 34. Multithreading: GCD Thread Pool Concurrent Queue 2-Core Processor Thread Thread Block 3 2 A D Thread Block 1 C B
  • 35. Multithreading: GCD Thread Pool Concurrent Queue Thread 2 2-Core Processor Thread Block 3 A D Thread Block 1 C B
  • 36. Block Delegation Delegates are essentially protocols that specify a list of method callbacks These method callbacks can be easily replaced with block callbacks Rule of thumb: 3 or less delegate callbacks should be handled using blocks.
  • 37. Block Delegation Advantages: No additional protocols No need to conform to a protocol Easy to change block callbacks dynamically
  • 38. Block Delegation Disadvantages: May not be appropriate when more than 3 callbacks are needed
  • 40. Template Method Sometimes algorithms differ by only a few lines Those few lines can be replaced by a virtual method Subclasses define the virtual method
  • 41. Template Method Let’s use blocks instead! Advantages: No need for subclassing May not need a new class at all Template can be changed dynamically
  • 42. Template Method - (void)doSomethingUsingBlock:(dispatch_block_t)block { // Do something block(); // Do some more stuff }
  • 44. Debug Mode + (void)whileInDebug:(MyBlock)block { #if defined(DEBUG) NSParameterAssert(block); block(); #endif }
  • 45. Lock Handling // Python convenient lock handler with myLock: // Do something // Can’t forget to lock/unlock
  • 46. Lock Handling + (void)withLock:(NSLock)lock executeBlock:(MyBlock)block { NSParameterAssert(lock && block); [lock lock]; block(); [lock unlock]; }
  • 47. Builder Pattern Some objects have complex structures that vary widely between uses Examples: Database tables, UITableView A block can define the construction of an object
  • 48. Builder Pattern // Ruby on Rails database table construction create_table :person do |t| t.string :name, null: false t.integer :age, null: false t.float :weight end
  • 49. Builder Pattern // Contrived example, but very feasible. // Creating a custom table view form. [RBTableView tableViewUsingBlock:^(RBTableView * t) { [t addStringField:@“name” required:YES]; [t addIntegerField:@“age” required:YES]; [t addFloatField:@“weight” required:NO]; }];
  • 50. Lockless Exclusion Accessor Thread-sensitive code is called critical code GCD allows for lockless-exclusion Lockless code is faster than lock code
  • 51. Lockless Exclusion Accessor Multi-threading challenges: Multi-threaded code must be properly synchronized It’s easy to forget to add thread-safety code
  • 52. Lockless Exclusion Accessor Solution: Have another object handle thread-safety Put critical code in a block Give the block to the thread-safety handler
  • 53. Lockless Exclusion Accessor - (void)accessSharedDataAsync:(void(^)(id sharedData))block { NSParameterAssert(block); // myQueue must be a serial queue! dispatch_async(myQueue, ^{ block([self sharedData]); }); }
  • 54. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue Block LEA C B A
  • 55. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue Block C LEA Block B Block A
  • 56. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block Block A C Block B
  • 57. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block Block A C Block B
  • 58. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block A B Block C
  • 59. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block A B Block C
  • 60. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block C A B
  • 61. Lockless Exclusion Accessor Shared Data Serial Shared Data Manager Queue LEA Block C A B
  • 62. Read/Write LEA Code that only reads from shared memory doesn’t need exclusive access Code that writes to shared memory needs exclusive access GCD barrier blocks and concurrent queues are a perfect solution
  • 63. Read/Write LEA // Read-only LEA - (void)accessSharedDataReadOnlyAsync:(void(^)(id sharedData))block { NSParameterAssert(block); // myQueue must be a concurrent queue! dispatch_async([self myQueue], ^{ block([self sharedData]); }); }
  • 64. Read/Write LEA // Read/write LEA - (void)accessSharedDataReadWriteAsync:(void(^)(id sharedData))block { NSParameterAssert(block); // myQueue must be a concurrent queue! dispatch_barrier_async([self myQueue], ^{ block([self sharedData]); }); }
  • 65. Read/Write LEA // All-in-one R/W-LEA - (void)accessSharedDataAsyncReadOnly:(BOOL)readOnly withBlock:(void(^)(id sharedData))block { if (readOnly) dispatch_async([self myQueue], ^{ block([self sharedData]); }); else dispatch_barrier_async([self myQueue], ^{ block([self sharedData]); }); }
  • 66. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Read Write Block
  • 67. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue Write R/W-LEA Block Read Block Read Block Read Block
  • 68. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Read Block Read Read Block Block Write Block
  • 69. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue Read R/W-LEA Block Read Read Read Block Block Block Write Block
  • 70. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue Read R/W-LEA Block Read Read Read Block Block Block Write Block
  • 71. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue Read R/W-LEA Block Read Read Read Block Block Block Write Block
  • 72. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Write Read Read Read Block Block Block Read Block
  • 73. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Write Read Read Read Block Block Block Read Block
  • 74. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Write Read Read Block Block
  • 75. Read/Write LEA Shared Data Concurrent Shared Data Manager Queue R/W-LEA Write Read Read Block Block
  • 76. Homework I have only touched the surface of what blocks can do Explore and find other design patterns you can convert to use blocks
  • 77. Want to Learn More? Blocks are best learned by playing with them Learn Ruby “The Pickaxe” Learn Racket 10 Uses for Blocks My Blog

Editor's Notes

  1. \n
  2. The practical application of blocks is language independent.\n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. ARC usually handles calling -copy for you.\nARC does not handle calling -copy before storing a block in a data structure.\n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. Continuations are powerful enough to build many features into a language. For example, you can add exceptions to a language using continuations. \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
  40. \n
  41. \n
  42. \n
  43. I’m assuming the 2-core processor is not hyper-threaded.\n
  44. I’m assuming the 2-core processor is not hyper-threaded.\n
  45. I’m assuming the 2-core processor is not hyper-threaded.\n
  46. I’m assuming the 2-core processor is not hyper-threaded.\n
  47. I’m assuming the 2-core processor is not hyper-threaded.\n
  48. I’m assuming the 2-core processor is not hyper-threaded.\n
  49. I’m assuming the 2-core processor is not hyper-threaded.\n
  50. I’m assuming the 2-core processor is not hyper-threaded.\n
  51. I’m assuming the 2-core processor is not hyper-threaded.\n
  52. I’m assuming the 2-core processor is not hyper-threaded.\n
  53. I’m assuming the 2-core processor is not hyper-threaded.\n
  54. I’m assuming the 2-core processor is not hyper-threaded.\n
  55. I’m assuming the 2-core processor is not hyper-threaded.\n
  56. I’m assuming the 2-core processor is not hyper-threaded.\n
  57. I’m assuming the 2-core processor is not hyper-threaded.\n
  58. I’m assuming the 2-core processor is not hyper-threaded.\n
  59. I’m assuming the 2-core processor is not hyper-threaded.\n
  60. I’m assuming the 2-core processor is not hyper-threaded.\n
  61. I’m assuming the 2-core processor is not hyper-threaded.\n
  62. I’m assuming the 2-core processor is not hyper-threaded.\n
  63. I’m assuming the 2-core processor is not hyper-threaded.\n
  64. I’m assuming the 2-core processor is not hyper-threaded.\n
  65. I’m assuming the 2-core processor is not hyper-threaded.\n
  66. I’m assuming the 2-core processor is not hyper-threaded.\n
  67. I’m assuming the 2-core processor is not hyper-threaded.\n
  68. I’m assuming the 2-core processor is not hyper-threaded.\n
  69. I’m assuming the 2-core processor is not hyper-threaded.\n
  70. I’m assuming the 2-core processor is not hyper-threaded.\n
  71. I’m assuming the 2-core processor is not hyper-threaded.\n
  72. I’m assuming the 2-core processor is not hyper-threaded.\n
  73. I’m assuming the 2-core processor is not hyper-threaded.\n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. The builder pattern is, in a way, the opposite of the template pattern. A template defines the main algorithm and the subroutines are added in via implementing virtual methods or blocks. The builder pattern defines the subroutines and the conductor method or block defines the main algorithm. \n
  86. \n
  87. Advantages: \nNo need to subclass UITableView (RBTableView technically).\nEasy to make custom table views.\n
  88. \n
  89. \n
  90. \n
  91. \n
  92. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  93. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  94. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  95. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  96. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  97. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  98. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  99. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  100. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  101. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  102. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  103. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  104. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  105. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  106. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  107. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  108. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  109. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  110. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  111. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  112. “Manager” does not imply the singleton pattern. The shared data manager could be any arbitrary object. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n