SlideShare a Scribd company logo
1 of 39
Download to read offline
Blocks
                         and
                 Grand Central Dispatch
                        Matteo Battaglio

                          Pragma Night @ Talent Garden

giovedì 7 febbraio 13
Blocks


                                 Pragma Night
giovedì 7 febbraio 13
What are Blocks?

         Blocks are:
           • an extension to the C language and its derivatives
                   Objective-C and C++, introduced by Apple
           • available in iOS SDK since version 4.0
           • already used by plenty of iOS frameworks’ APIs


                                                              Pragma Night
giovedì 7 febbraio 13
Benefits

           • more functional style of coding
           • less boilerplate code
           • more readable code
           • simplify event-driven scenarios (i.e. callbacks)
           • simplify multi-threading

                                                                Pragma Night
giovedì 7 febbraio 13
Definition


           • ‘block’ is the name Objective-C gives to the
                   concept of closure, that is:
                 • a pointer to a function
                 • a copy of some of the local variables of its
                        higher-order function



                                                                  Pragma Night
giovedì 7 febbraio 13
Syntax

          int multiplier = 7;


             Declaration of the variable
                                                           Definition of the variable ‘myBlock’,
                         ‘myBlock’.
                                                                using a block literal.
           The ‘^’ tells that its type is a block.


          int (^myBlock)(int) = ^(int num) { return num * multiplier; };


            Return type          Parameter list
                                                                          Body of the block.

                                                  The parameter is
                                                   named ‘num’.




                                                                                                  Pragma Night
giovedì 7 febbraio 13
Key features


           • allow code to be passed around for later
                   execution
           • access to the local variables of the function they
                   were declared in
           • mantain a state among calls

                                                            Pragma Night
giovedì 7 febbraio 13
Code example #1


          int multiplier = 7;

          // Declaring a block and assigning it to the variable ‘myBlock’

          int (^myBlock)(int) = ^(int num) { return num * multiplier; };



          // Calling the block

          printf(myBlock(3)); // prints '21'


                Calling a block in no different
                    than calling a function




                                                                            Pragma Night
giovedì 7 febbraio 13
Code example #2

          // Inline use of a block literal (as an actual parameter of a function)

          char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };

          qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
              char *left = *(char **)l;
              char *right = *(char **)r;
              return strncmp(left, right, 1);
          });

                                          qsort_b() will internally call the block many times, in order
                                                  to compare each pair of cells in the array

          // myCharacters is now { "Charles Condomine", "George", "TomJohn" }




                                                                                                          Pragma Night
giovedì 7 febbraio 13
Code example #3


          // Declaring a function that takes a block as parameter

          void myFunction(int (^aBlock)(void *, void *));



          // Declaring a function that returns a block

          void (^myFunction(int a, int b))(double, double);



                  Function name   Function parameters   The function’s return type is a block with signature
                                                               void (^)(double, double)




                                                                                                         Pragma Night
giovedì 7 febbraio 13
Code example #4


          // Defining a custom name for our block type to improve code style

          typedef void (^MyBlockType)(double, double);


          // Variable and function declarations now look much more readable

          MyBlockType myBlock = ^(double a, double b) { printf("hey!"); };

          MyBlockType myFunction(int a, int b, MyBlockType aBlock);




                                                                               Pragma Night
giovedì 7 febbraio 13
Variables caveats
           • non-local variables in blocks are constant and
                   read-only
                                           Trying to modify ‘i’ from inside the block
                                                results in a compilation error.




           • in order to make them ‘live’ and writable the
                   __block type specifier must be added to their
                   declaration

                                                                                        Pragma Night
giovedì 7 febbraio 13
__block
            int myFunction() {

                    __block int i = 0;

                    void (^myBlock)(void) = ^{
                        i++;
                        printf("i has the value %d", i); // prints 'i has the value 1'
                    };

            }



           • what __block does is:
            • pass the variable by reference - rather than by
                        value - to the block
                 • create a strong (as opposed to weak) reference
                        to that variable
                                                                                         Pragma Night
giovedì 7 febbraio 13
State representation

           • blocks can use variables marked with __block to
                   keep a state among calls

            int myFunction() {

                    __block int i = 0;

                    void (^myBlock)(void) = ^{
                        i++;
                        printf("i has the value %d", i);
                    };

                    myBlock(); // prints 'i has the value 1'

                    myBlock(); // prints 'i has the value 2'

            }




                                                               Pragma Night
giovedì 7 febbraio 13
Information hiding

                                                                    The outer block defines a local variable that is used inside the
                                                                  inner block to mantain a state: this way we are keeping the sum
                                                                            variable hidden to the rest of the program
          int array[] = {4, 5, 2, 6, 1};

          qsort_b(array, 5, sizeof(int), ^(void) {

                  __block int sum = 0;

              return ^(const void *a, const void *b) {
                  sum += (int)a;
                  return a - b;
              };                        The inner block is what gets passed to the qsort_b() function
          }());


                   These parentheses tell us that the outer block is
                     executed, and not passed to qsort_b.




                                                                                                                             Pragma Night
giovedì 7 febbraio 13
__block implications

           • variables marked with __block are shared
                   between their lexical scope and all blocks and
                   block copies declared or created within that scope
                 • multiple blocks can simultaneously use a shared
                        variable
                 • when a block is copied (i.e. it is moved from the
                        stack to the heap), they survive the destruction
                        of their stack frame


                                                                    Pragma Night
giovedì 7 febbraio 13
Memory concerns
           • a block is allowed to access self
            • self is passed as a strong reference
            • this could lead to a ‘retain cicle’
            • trick: define a __weak reference to self
                        int myFunction() {

                            __weak MyObject weakSelf = self;

                            void (^myBlock)(void) = ^{

                                [weakSelf someMethod];

                            }
                        }



                                                               Pragma Night
giovedì 7 febbraio 13
Common scenarios in the SDK
        Collection enumeration

          NSArray *array = [NSArray arrayWithObjects:@"One", @"Two", @"Three", @“Four”, nil];

                                    It substitutes the for loop.
                        Now the collections can enumerate themselves.

          [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
              NSLog(@"array[%d] = %@", idx, obj);
          }];                                                    Setting *stop to YES inside the
                                                                block will stop the enumeration



          [array enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock:
              ^(id obj, NSUInteger idx, BOOL *stop) {
                  NSLog(@"array[%d] = %@", idx, obj);
              }                                              Making an enumeration concurrent
          ];                                                    is a matter of adding an option!




                                                                                                   Pragma Night
giovedì 7 febbraio 13
Common scenarios in the SDK
         View animations
          - (void)animateView:(UIView*)view {
              CGRect cacheFrame = [view frame];

                  [UIView animateWithDuration:1.5 animations:
                  ^{
                      CGRect newFrame = [view frame];
                      newFrame.origin.y = newFrame.origin.y + 250.0;
                      [view setFrame:newFrame];
                      [view setAlpha:0.5];
                  }
                                    completion:
                  ^(BOOL finished) {
                      if (finished) {
                          sleep(1);
                          [view setFrame:cacheFrame];
                          [view setAlpha:1.0];
                      }
                  }];
          }




                                                                       Pragma Night
giovedì 7 febbraio 13
Common scenarios in the SDK
        Notification observers

            NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
            NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];

            [center addObserverForName:SomeNotificationName
                                object:nil
                                 queue:mainQueue
                            usingBlock:^(NSNotification *note) {
                                           NSLog(@"Notification received");
                                       }];




                                                                                   Pragma Night
giovedì 7 febbraio 13
Common scenarios in the SDK
        Operations queues
            NSOperationQueue *queue = [[NSOperationQueue alloc] init];

            [queue addOperationWithBlock:^{
                NSLog(@"This block is run in the operation");
            }];
                                                  Wraps the block inside a NSOperation


                         A single NSBlockOperation can execute multiple blocks concurrently

            NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
                NSLog(@"This block is run in the operation");
            }];

            [operation addExecutionBlock:^{
                NSLog(@"NSBlockOperations can execute multiple blocks ");
            }];

            [operation setCompletionBlock:^{
                NSLog(@"This Code Runs Once The Operation Has Finished");
            }];


                                                                                              Pragma Night
giovedì 7 febbraio 13
Grand Central Dispatch


                         Pragma Night
giovedì 7 febbraio 13
What is Grand Central Dispatch?
          Grand Central Dispatch (GCD) is:
           • a set of language features and libraries to improve
                   and simplify the act of writing concurrent code
           • more efficient than threads
           • implemented at all levels of APIs in iOS (BSD
                   subsystem, CoreFoundation, Cocoa)



                                                                Pragma Night
giovedì 7 febbraio 13
Concept

           • GCD is based on the Thread Pool pattern
            • a (small) number of threads is created
            • (possibly lots of) tasks are added to queues in
                        order to be executed
                 • an algorithm handles the creation/destruction of
                        threads, and the scheduling of tasks


                                                               Pragma Night
giovedì 7 febbraio 13
Implementation


           • dispatch queues
           • dispatch sources
           • dispatch groups
           • dispatch semaphores

                                         Pragma Night
giovedì 7 febbraio 13
Dispatch queues
         • execute tasks always in a first-in, first-out order
         • 2 types:
           • serial queues (aka private dispatch queues)
             • one and only one task running at a time
             • the main dispatch queue is a peculiar one
           • concurrent queues (aka global dispatch queues)
             • tasks started in order but run concurrently
             • four such queues, differing only by priority level,
                        are made available by the os
                                                             Pragma Night
giovedì 7 febbraio 13
Serial queues

         • one and only one task running at a time
         • the main dispatch queue is serial
          • tied to the main thread and application’s run loop
          • interleaves queued tasks with other event
                        sources
                • often used as the key synchronization point for
                        the application

                                                             Pragma Night
giovedì 7 febbraio 13
Creating serial queues

          // Creating a serial dispatch queue
          dispatch_queue_t queue;
          queue = dispatch_queue_create("com.example.MyQueue", NULL);



          // Getting the dispatch queue on which the currently executing block is running
          dispatch_queue_t current_queue;
          current_queue = dispatch_get_current_queue();



          // Getting the main dispatch queue
          dispatch_queue_t main_queue;
          main_queue = dispatch_get_main_queue();




                                                                                     Pragma Night
giovedì 7 febbraio 13
Concurrent queues


         • tasks are started in order but run concurrently
         • the system provides four concurrent queues
          • they are global to the application
          • they differ only by priority level

                                                        Pragma Night
giovedì 7 febbraio 13
Creating concurrent queues

          // Getting one of the four global dispatch queues
          dispatch_queue_t global_queue;
          global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

          // The four priority levels, ranked high to low, are
          DISPATCH_QUEUE_PRIORITY_HIGH
          DISPATCH_QUEUE_PRIORITY_DEFAULT
          DISPATCH_QUEUE_PRIORITY_LOW
          DISPATCH_QUEUE_PRIORITY_BACKGROUND



          // Creating a concurrent dispatch queue
          dispatch_queue_t queue;
          queue = dispatch_queue_create("com.example.MyQueue", DISPATCH_QUEUE_CONCURRENT);




                                                                                     Pragma Night
giovedì 7 febbraio 13
Using queues

           • dispatch_async(queue,                block)

                 • submits a block for asynchronous execution on
                        a dispatch queue and returns immediately
           • dispatch_sync(queue,               block)

                 • submits a block object for execution on a
                        dispatch queue and waits until that block
                        completes


                                                                    Pragma Night
giovedì 7 febbraio 13
Using queues
       • dispatch_after(when,                        queue, block)

             • enqueue a block for execution at the specified time
       • dispatch_apply(iterations,                           queue, block)

             • submits a block to a dispatch queue for multiple
                        invocations
       • dispatch_once(queue,                        block)

             • executes a block object once and only once for the
                        lifetime of an application

                                                                       Pragma Night
giovedì 7 febbraio 13
Dispatch sources

           • allow the client to register blocks or functions to
                   execute asynchronously upon system events
           • unlike manually-put tasks, they remain attached to
                   their queue, and submit their associated task to it
                   whenever the corresponding event occurs
           • to prevent backlogging, they can coalesce events
           • types of sources: signal, timer, descriptor, process,
                   Mach port, custom

                                                                 Pragma Night
giovedì 7 febbraio 13
Dispatch source example
      dispatch_source_t CreateDispatchTimer(uint64_t interval,
                                            uint64_t leeway,
                                            dispatch_queue_t queue,
                                            dispatch_block_t block) {
          dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
                                                           0, 0, queue);
          if (timer) {
              dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
              dispatch_source_set_event_handler(timer, block);
              dispatch_resume(timer);
          }
          return timer;
      }

      void MyCreateTimer() {
          dispatch_source_t aTimer = CreateDispatchTimer(30ull * NSEC_PER_SEC,
                                                         1ull * NSEC_PER_SEC,
                                                         dispatch_get_main_queue(),
                                                         ^{ MyPeriodicTask(); });

              // Store it somewhere for later use.
              if (aTimer) {
                  MyStoreTimer(aTimer);
              }
      }



                                                                                      Pragma Night
giovedì 7 febbraio 13
Dispatch groups


           • are objects that allow several tasks to be grouped
                   for later joining.
           • a task can be added to a queue as a member of a
                   group, and then the client can use the group object
                   to wait until all of the tasks in that group have
                   completed



                                                                Pragma Night
giovedì 7 febbraio 13
Dispatch group example

      dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
      dispatch_group_t group = dispatch_group_create();

      // Add a task to the group
      dispatch_group_async(group, queue, ^{
          // Some asynchronous work
      });

      //
      // Do some other work while the tasks execute...
      //

      // When you cannot make any more forward progress,
      // wait on the group to block the current thread.
      dispatch_group_wait(group, DISPATCH_TIME_FOREVER);

      // Release the group when it is no longer needed.
      dispatch_release(group);




                                                                                   Pragma Night
giovedì 7 febbraio 13
Dispatch semaphores
           • useful for regulating the use of finite resources
              // Example: limiting the number of file descriptors open concurrently



              // Create the semaphore, specifying the initial pool size
              dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2);

              // Wait for a free file descriptor
              dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER);
              fd = open("/etc/services", O_RDONLY);

              // Release the file descriptor when done
              close(fd);
              dispatch_semaphore_signal(fd_sema);




                                                                                       Pragma Night
giovedì 7 febbraio 13
References
           •       WWDC 2011 - session 308:
                   Blocks and Grand Central Dispatch in Practice
           •       Apple documentation
                 •      Blocks Programming Topics
                 •      Concurrency Programming Guide
                 •      Grand Central Dispatch (GCD) Reference
           •       Book: Pro Multithreading and Memory Management
                   for iOS and OS X: with ARC, Grand Central
                   Dispatch, and Blocks

                                                                   Pragma Night
giovedì 7 febbraio 13
Thank You!

                        matteo.battaglio@pragmamark.org
                                                          Pragma Night
giovedì 7 febbraio 13

More Related Content

What's hot

Ti1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and ScopesTi1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and Scopes
Eelco Visser
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
Edward Chen
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
Princess Sam
 
Write Your Own JVM Compiler
Write Your Own JVM CompilerWrite Your Own JVM Compiler
Write Your Own JVM Compiler
Erin Dees
 
VJET bringing the best of Java and JavaScript together
VJET bringing the best of Java and JavaScript togetherVJET bringing the best of Java and JavaScript together
VJET bringing the best of Java and JavaScript together
Justin Early
 

What's hot (17)

C++ programming with jni
C++ programming with jniC++ programming with jni
C++ programming with jni
 
JavaScript Essentials
JavaScript EssentialsJavaScript Essentials
JavaScript Essentials
 
Lecture21
Lecture21Lecture21
Lecture21
 
Variables: names, bindings, type, scope
Variables: names, bindings, type, scopeVariables: names, bindings, type, scope
Variables: names, bindings, type, scope
 
201005 accelerometer and core Location
201005 accelerometer and core Location201005 accelerometer and core Location
201005 accelerometer and core Location
 
Modern Objective-C @ Pragma Night
Modern Objective-C @ Pragma NightModern Objective-C @ Pragma Night
Modern Objective-C @ Pragma Night
 
Parte II Objective C
Parte II   Objective CParte II   Objective C
Parte II Objective C
 
Magic in ruby
Magic in rubyMagic in ruby
Magic in ruby
 
Ti1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and ScopesTi1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and Scopes
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
Lec 42.43 - virtual.functions
Lec 42.43 - virtual.functionsLec 42.43 - virtual.functions
Lec 42.43 - virtual.functions
 
Playfulness at Work
Playfulness at WorkPlayfulness at Work
Playfulness at Work
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 
Write Your Own JVM Compiler
Write Your Own JVM CompilerWrite Your Own JVM Compiler
Write Your Own JVM Compiler
 
VJET bringing the best of Java and JavaScript together
VJET bringing the best of Java and JavaScript togetherVJET bringing the best of Java and JavaScript together
VJET bringing the best of Java and JavaScript together
 
pointers,virtual functions and polymorphism
pointers,virtual functions and polymorphismpointers,virtual functions and polymorphism
pointers,virtual functions and polymorphism
 

Similar to Objective-C Blocks and Grand Central Dispatch

polymorpisum-140106223024-phpapp01.pdf
polymorpisum-140106223024-phpapp01.pdfpolymorpisum-140106223024-phpapp01.pdf
polymorpisum-140106223024-phpapp01.pdf
BapanKar2
 
Scripting
ScriptingScripting
Scripting
aztack
 
Java session05
Java session05Java session05
Java session05
Niit Care
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
rashmita_mishra
 

Similar to Objective-C Blocks and Grand Central Dispatch (20)

Blocks and GCD(Grand Central Dispatch)
Blocks and GCD(Grand Central Dispatch)Blocks and GCD(Grand Central Dispatch)
Blocks and GCD(Grand Central Dispatch)
 
Moose
MooseMoose
Moose
 
Master in javascript
Master in javascriptMaster in javascript
Master in javascript
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCD
 
Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)Objective-C A Beginner's Dive (with notes)
Objective-C A Beginner's Dive (with notes)
 
Objective-C A Beginner's Dive
Objective-C A Beginner's DiveObjective-C A Beginner's Dive
Objective-C A Beginner's Dive
 
polymorpisum-140106223024-phpapp01.pdf
polymorpisum-140106223024-phpapp01.pdfpolymorpisum-140106223024-phpapp01.pdf
polymorpisum-140106223024-phpapp01.pdf
 
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
JavaScript Closures for Dummies & JavaScript prototype, closures and OOP.
 
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
Vladymyr Bahrii Understanding polymorphism in C++ 16.11.17
 
Lombok Features
Lombok FeaturesLombok Features
Lombok Features
 
Back to the Future with TypeScript
Back to the Future with TypeScriptBack to the Future with TypeScript
Back to the Future with TypeScript
 
Spock
SpockSpock
Spock
 
Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0Fluent Development with FLOW3 1.0
Fluent Development with FLOW3 1.0
 
Scripting
ScriptingScripting
Scripting
 
Fields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptxFields in Java and Kotlin and what to expect.pptx
Fields in Java and Kotlin and what to expect.pptx
 
Java session05
Java session05Java session05
Java session05
 
Block introduce
Block introduceBlock introduce
Block introduce
 
New microsoft office word document (2)
New microsoft office word document (2)New microsoft office word document (2)
New microsoft office word document (2)
 
C questions
C questionsC questions
C questions
 
Ruby Blocks
Ruby BlocksRuby Blocks
Ruby Blocks
 

More from pragmamark

Automatic Reference Counting
Automatic Reference Counting Automatic Reference Counting
Automatic Reference Counting
pragmamark
 

More from pragmamark (8)

Automatic Reference Counting
Automatic Reference CountingAutomatic Reference Counting
Automatic Reference Counting
 
Modern Objective-C
Modern Objective-CModern Objective-C
Modern Objective-C
 
Il gruppo Pragma mark
Il gruppo Pragma markIl gruppo Pragma mark
Il gruppo Pragma mark
 
iOS Ecosystem
iOS EcosystemiOS Ecosystem
iOS Ecosystem
 
Objective-C
Objective-CObjective-C
Objective-C
 
Xcode - Just do it
Xcode - Just do itXcode - Just do it
Xcode - Just do it
 
Automatic Reference Counting
Automatic Reference Counting Automatic Reference Counting
Automatic Reference Counting
 
iOS Api Client: soluzioni a confronto
iOS Api Client: soluzioni a confrontoiOS Api Client: soluzioni a confronto
iOS Api Client: soluzioni a confronto
 

Recently uploaded

Recently uploaded (20)

Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Designing for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at ComcastDesigning for Hardware Accessibility at Comcast
Designing for Hardware Accessibility at Comcast
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on ThanabotsContinuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
Continuing Bonds Through AI: A Hermeneutic Reflection on Thanabots
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 
WebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM PerformanceWebAssembly is Key to Better LLM Performance
WebAssembly is Key to Better LLM Performance
 
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
1111 ChatGPT Prompts PDF Free Download - Prompts for ChatGPT
 
TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024TopCryptoSupers 12thReport OrionX May2024
TopCryptoSupers 12thReport OrionX May2024
 

Objective-C Blocks and Grand Central Dispatch

  • 1. Blocks and Grand Central Dispatch Matteo Battaglio Pragma Night @ Talent Garden giovedì 7 febbraio 13
  • 2. Blocks Pragma Night giovedì 7 febbraio 13
  • 3. What are Blocks? Blocks are: • an extension to the C language and its derivatives Objective-C and C++, introduced by Apple • available in iOS SDK since version 4.0 • already used by plenty of iOS frameworks’ APIs Pragma Night giovedì 7 febbraio 13
  • 4. Benefits • more functional style of coding • less boilerplate code • more readable code • simplify event-driven scenarios (i.e. callbacks) • simplify multi-threading Pragma Night giovedì 7 febbraio 13
  • 5. Definition • ‘block’ is the name Objective-C gives to the concept of closure, that is: • a pointer to a function • a copy of some of the local variables of its higher-order function Pragma Night giovedì 7 febbraio 13
  • 6. Syntax int multiplier = 7; Declaration of the variable Definition of the variable ‘myBlock’, ‘myBlock’. using a block literal. The ‘^’ tells that its type is a block. int (^myBlock)(int) = ^(int num) { return num * multiplier; }; Return type Parameter list Body of the block. The parameter is named ‘num’. Pragma Night giovedì 7 febbraio 13
  • 7. Key features • allow code to be passed around for later execution • access to the local variables of the function they were declared in • mantain a state among calls Pragma Night giovedì 7 febbraio 13
  • 8. Code example #1 int multiplier = 7; // Declaring a block and assigning it to the variable ‘myBlock’ int (^myBlock)(int) = ^(int num) { return num * multiplier; }; // Calling the block printf(myBlock(3)); // prints '21' Calling a block in no different than calling a function Pragma Night giovedì 7 febbraio 13
  • 9. Code example #2 // Inline use of a block literal (as an actual parameter of a function) char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" }; qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) { char *left = *(char **)l; char *right = *(char **)r; return strncmp(left, right, 1); }); qsort_b() will internally call the block many times, in order to compare each pair of cells in the array // myCharacters is now { "Charles Condomine", "George", "TomJohn" } Pragma Night giovedì 7 febbraio 13
  • 10. Code example #3 // Declaring a function that takes a block as parameter void myFunction(int (^aBlock)(void *, void *)); // Declaring a function that returns a block void (^myFunction(int a, int b))(double, double); Function name Function parameters The function’s return type is a block with signature void (^)(double, double) Pragma Night giovedì 7 febbraio 13
  • 11. Code example #4 // Defining a custom name for our block type to improve code style typedef void (^MyBlockType)(double, double); // Variable and function declarations now look much more readable MyBlockType myBlock = ^(double a, double b) { printf("hey!"); }; MyBlockType myFunction(int a, int b, MyBlockType aBlock); Pragma Night giovedì 7 febbraio 13
  • 12. Variables caveats • non-local variables in blocks are constant and read-only Trying to modify ‘i’ from inside the block results in a compilation error. • in order to make them ‘live’ and writable the __block type specifier must be added to their declaration Pragma Night giovedì 7 febbraio 13
  • 13. __block int myFunction() { __block int i = 0; void (^myBlock)(void) = ^{ i++; printf("i has the value %d", i); // prints 'i has the value 1' }; } • what __block does is: • pass the variable by reference - rather than by value - to the block • create a strong (as opposed to weak) reference to that variable Pragma Night giovedì 7 febbraio 13
  • 14. State representation • blocks can use variables marked with __block to keep a state among calls int myFunction() { __block int i = 0; void (^myBlock)(void) = ^{ i++; printf("i has the value %d", i); }; myBlock(); // prints 'i has the value 1' myBlock(); // prints 'i has the value 2' } Pragma Night giovedì 7 febbraio 13
  • 15. Information hiding The outer block defines a local variable that is used inside the inner block to mantain a state: this way we are keeping the sum variable hidden to the rest of the program int array[] = {4, 5, 2, 6, 1}; qsort_b(array, 5, sizeof(int), ^(void) { __block int sum = 0; return ^(const void *a, const void *b) { sum += (int)a; return a - b; }; The inner block is what gets passed to the qsort_b() function }()); These parentheses tell us that the outer block is executed, and not passed to qsort_b. Pragma Night giovedì 7 febbraio 13
  • 16. __block implications • variables marked with __block are shared between their lexical scope and all blocks and block copies declared or created within that scope • multiple blocks can simultaneously use a shared variable • when a block is copied (i.e. it is moved from the stack to the heap), they survive the destruction of their stack frame Pragma Night giovedì 7 febbraio 13
  • 17. Memory concerns • a block is allowed to access self • self is passed as a strong reference • this could lead to a ‘retain cicle’ • trick: define a __weak reference to self int myFunction() { __weak MyObject weakSelf = self; void (^myBlock)(void) = ^{ [weakSelf someMethod]; } } Pragma Night giovedì 7 febbraio 13
  • 18. Common scenarios in the SDK Collection enumeration NSArray *array = [NSArray arrayWithObjects:@"One", @"Two", @"Three", @“Four”, nil]; It substitutes the for loop. Now the collections can enumerate themselves. [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"array[%d] = %@", idx, obj); }]; Setting *stop to YES inside the block will stop the enumeration [array enumerateObjectsWithOptions: NSEnumerationConcurrent usingBlock: ^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"array[%d] = %@", idx, obj); } Making an enumeration concurrent ]; is a matter of adding an option! Pragma Night giovedì 7 febbraio 13
  • 19. Common scenarios in the SDK View animations - (void)animateView:(UIView*)view { CGRect cacheFrame = [view frame]; [UIView animateWithDuration:1.5 animations: ^{ CGRect newFrame = [view frame]; newFrame.origin.y = newFrame.origin.y + 250.0; [view setFrame:newFrame]; [view setAlpha:0.5]; } completion: ^(BOOL finished) { if (finished) { sleep(1); [view setFrame:cacheFrame]; [view setAlpha:1.0]; } }]; } Pragma Night giovedì 7 febbraio 13
  • 20. Common scenarios in the SDK Notification observers NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; [center addObserverForName:SomeNotificationName object:nil queue:mainQueue usingBlock:^(NSNotification *note) { NSLog(@"Notification received"); }]; Pragma Night giovedì 7 febbraio 13
  • 21. Common scenarios in the SDK Operations queues NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperationWithBlock:^{ NSLog(@"This block is run in the operation"); }]; Wraps the block inside a NSOperation A single NSBlockOperation can execute multiple blocks concurrently NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"This block is run in the operation"); }]; [operation addExecutionBlock:^{ NSLog(@"NSBlockOperations can execute multiple blocks "); }]; [operation setCompletionBlock:^{ NSLog(@"This Code Runs Once The Operation Has Finished"); }]; Pragma Night giovedì 7 febbraio 13
  • 22. Grand Central Dispatch Pragma Night giovedì 7 febbraio 13
  • 23. What is Grand Central Dispatch? Grand Central Dispatch (GCD) is: • a set of language features and libraries to improve and simplify the act of writing concurrent code • more efficient than threads • implemented at all levels of APIs in iOS (BSD subsystem, CoreFoundation, Cocoa) Pragma Night giovedì 7 febbraio 13
  • 24. Concept • GCD is based on the Thread Pool pattern • a (small) number of threads is created • (possibly lots of) tasks are added to queues in order to be executed • an algorithm handles the creation/destruction of threads, and the scheduling of tasks Pragma Night giovedì 7 febbraio 13
  • 25. Implementation • dispatch queues • dispatch sources • dispatch groups • dispatch semaphores Pragma Night giovedì 7 febbraio 13
  • 26. Dispatch queues • execute tasks always in a first-in, first-out order • 2 types: • serial queues (aka private dispatch queues) • one and only one task running at a time • the main dispatch queue is a peculiar one • concurrent queues (aka global dispatch queues) • tasks started in order but run concurrently • four such queues, differing only by priority level, are made available by the os Pragma Night giovedì 7 febbraio 13
  • 27. Serial queues • one and only one task running at a time • the main dispatch queue is serial • tied to the main thread and application’s run loop • interleaves queued tasks with other event sources • often used as the key synchronization point for the application Pragma Night giovedì 7 febbraio 13
  • 28. Creating serial queues // Creating a serial dispatch queue dispatch_queue_t queue; queue = dispatch_queue_create("com.example.MyQueue", NULL); // Getting the dispatch queue on which the currently executing block is running dispatch_queue_t current_queue; current_queue = dispatch_get_current_queue(); // Getting the main dispatch queue dispatch_queue_t main_queue; main_queue = dispatch_get_main_queue(); Pragma Night giovedì 7 febbraio 13
  • 29. Concurrent queues • tasks are started in order but run concurrently • the system provides four concurrent queues • they are global to the application • they differ only by priority level Pragma Night giovedì 7 febbraio 13
  • 30. Creating concurrent queues // Getting one of the four global dispatch queues dispatch_queue_t global_queue; global_queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // The four priority levels, ranked high to low, are DISPATCH_QUEUE_PRIORITY_HIGH DISPATCH_QUEUE_PRIORITY_DEFAULT DISPATCH_QUEUE_PRIORITY_LOW DISPATCH_QUEUE_PRIORITY_BACKGROUND // Creating a concurrent dispatch queue dispatch_queue_t queue; queue = dispatch_queue_create("com.example.MyQueue", DISPATCH_QUEUE_CONCURRENT); Pragma Night giovedì 7 febbraio 13
  • 31. Using queues • dispatch_async(queue, block) • submits a block for asynchronous execution on a dispatch queue and returns immediately • dispatch_sync(queue, block) • submits a block object for execution on a dispatch queue and waits until that block completes Pragma Night giovedì 7 febbraio 13
  • 32. Using queues • dispatch_after(when, queue, block) • enqueue a block for execution at the specified time • dispatch_apply(iterations, queue, block) • submits a block to a dispatch queue for multiple invocations • dispatch_once(queue, block) • executes a block object once and only once for the lifetime of an application Pragma Night giovedì 7 febbraio 13
  • 33. Dispatch sources • allow the client to register blocks or functions to execute asynchronously upon system events • unlike manually-put tasks, they remain attached to their queue, and submit their associated task to it whenever the corresponding event occurs • to prevent backlogging, they can coalesce events • types of sources: signal, timer, descriptor, process, Mach port, custom Pragma Night giovedì 7 febbraio 13
  • 34. Dispatch source example dispatch_source_t CreateDispatchTimer(uint64_t interval, uint64_t leeway, dispatch_queue_t queue, dispatch_block_t block) { dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); if (timer) { dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway); dispatch_source_set_event_handler(timer, block); dispatch_resume(timer); } return timer; } void MyCreateTimer() { dispatch_source_t aTimer = CreateDispatchTimer(30ull * NSEC_PER_SEC, 1ull * NSEC_PER_SEC, dispatch_get_main_queue(), ^{ MyPeriodicTask(); }); // Store it somewhere for later use. if (aTimer) { MyStoreTimer(aTimer); } } Pragma Night giovedì 7 febbraio 13
  • 35. Dispatch groups • are objects that allow several tasks to be grouped for later joining. • a task can be added to a queue as a member of a group, and then the client can use the group object to wait until all of the tasks in that group have completed Pragma Night giovedì 7 febbraio 13
  • 36. Dispatch group example dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); // Add a task to the group dispatch_group_async(group, queue, ^{ // Some asynchronous work }); // // Do some other work while the tasks execute... // // When you cannot make any more forward progress, // wait on the group to block the current thread. dispatch_group_wait(group, DISPATCH_TIME_FOREVER); // Release the group when it is no longer needed. dispatch_release(group); Pragma Night giovedì 7 febbraio 13
  • 37. Dispatch semaphores • useful for regulating the use of finite resources // Example: limiting the number of file descriptors open concurrently // Create the semaphore, specifying the initial pool size dispatch_semaphore_t fd_sema = dispatch_semaphore_create(getdtablesize() / 2); // Wait for a free file descriptor dispatch_semaphore_wait(fd_sema, DISPATCH_TIME_FOREVER); fd = open("/etc/services", O_RDONLY); // Release the file descriptor when done close(fd); dispatch_semaphore_signal(fd_sema); Pragma Night giovedì 7 febbraio 13
  • 38. References • WWDC 2011 - session 308: Blocks and Grand Central Dispatch in Practice • Apple documentation • Blocks Programming Topics • Concurrency Programming Guide • Grand Central Dispatch (GCD) Reference • Book: Pro Multithreading and Memory Management for iOS and OS X: with ARC, Grand Central Dispatch, and Blocks Pragma Night giovedì 7 febbraio 13
  • 39. Thank You! matteo.battaglio@pragmamark.org Pragma Night giovedì 7 febbraio 13