Summary of Grand Central Dispatch (GCD)

6:41 AM , 0 Comments



Summary of Grand Central Dispatch (GCD)
   Grand Central Dispatch (GCD) is a library that provides support for concurrent code execution on IOS and OS X. Before GCD, developers were mainly using tools like NSThread or PerformSelectorInBackground to implement simple multithreading applications on IOS or Mac. After GCD got released, Apple also published another higher level Objective-C based API called NSOperationQueue since GCD API is based on C. It makes life much easier for Objective-C developers.

The Graph below summarizes the evolution of the tools for multithreading application development from Apple.
With newer and better tools like GCD and NSOperationQueue, one should never want to use NSThread or performSelector to create a multi-threading application. The link below details the reasons.

http://stackoverflow.com/questions/19500820/gcd-vs-performselectorinbackground-performselectoronmainthread

Within GCD, there are different queue types and their relationship is mapped below.


Below are some examples of how to use each queue in GCD to solve specific concurrent programming issues.
  1. dispatch_queue_create: it can create custom queue
          dispatch_queue_t q = dispatch_queue_create(“com.example.myQueue”, NULL);
          NULL means serial, 0 means concurrent. Better to use DISPATCH_QUEUE_CONCURRENT and DISPATCH_QUEUE_SERIAL instead of 0 and NULL.

  1. dispatch_set_target_queue: change the priority of the queue
dispatch_queue_t q_1 = dispatch_queue_create(“com.example.myQueue”, NULL);
   dispatch_queue_t q_2 =  
dispatch_get_globale_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
   dispatch_set_target_queue(q_1, q_2); // set q_1 same priority as 1_2
  1. dispatch_after: Add task into queue after certain amount of time
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC));
dispatch_after(time, dispatch_get_main_queue(), ^{
NSLog(“wait at least 2 seconds to put into queue”);
          });

  1. dispatch_group_t/dispatch_notify
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t g = dispatch_group_create();
dispatch_group_async(g,q,^{});
dispatch_group_async(g,q,^{});
dispatch_group_notify(g,dispatch_get_main_queue(),^{});

  1. dispatch_barrier_async: make sure at the moment only one block is currently execute
dispatch_async(queue, ^{ // block for reading});
dispatch_barrier_async(queue, ^{ // block for writing });
dispatch_async(queue, ^{ // block for reading});

  1. dispatch_apply
dispatch_apply(5, queue, ^(size_t index){ });

  1. dispatch_suspend/dispatch_resume
dispatch_suspend(queue);
dispatch_resume(queue);

  1. dispatch_semaphore_wait: compare with barrier, semaphore can use to control for a small portion of the source code that has smaller granularity than serial dispatch queue or dispatch_barrier_async function.
dispatch_semaphore_t  s = dispatch_semaphore_create(1);
dispatch_async(queue, ^{
dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);
// task you want to finish before move forward
dispatch_semaphore_signal(s);
});

  1. dispatch_once: used often in singleton design pattern
static dispatch_once_t token;
dispatch_once(&token, ^{));

Unknown

Some say he’s half man half fish, others say he’s more of a seventy/thirty split. Either way he’s a fishy bastard.

0 comments: