MikeG
MikeG

Reputation: 4044

Grand Central Dispatch, not sure if I am understanding this completely, here is how I am using it

I am trying to get the hang of Grand Central Dispatch to make improvements to the overall efficiency of my code, however, I am not entirely certain of how to use it. Below are examples of my current (possibly horribly mislead) assumptions on GCD, based on a tutorial as well as numerous other stack overflow questions, a few swift blogs, and some other random websites....

 dispatch_async(dispatch_get_main_queue()){
    //this will execute the task wihtin this closure, asynchonously, meaning 
    //that it does not block the thread, yet the code within the closure will       
    //be executed serailly, meaning each line must finish before proceeding
print(1)
print(2)
print(3)
print(4)
//this will print 1,2,3,4, in that exact order, everytime. But since it is 
//called asynchronously it returns immediatley after initiating the task, and 
//thus does not block the UI from being interacted with
}

dispatch_sync(dispatch_get_main_queue()){
 //this will execute the taks within the closure synchronously, meaning that it WILL block
 //the current thread until the task is completed at which point it will return and make the
//thread available again. The main queue is a serial queue, so each line will be started
//and finish before the line after it is called.
  print(1)
  print(2)
  print(3)
  print(4)
  //this will print 1,2,3,4, in that exact order, everytime. Because it is called synchronously
  //and on the main queue, it will block the UI. The UI will not become interactive again
  //until this function returns, and it will not return until "4" is printed.
}

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.rawValue), 0)){
  //this will execute the task within the closure asycnrhonously, meaning that
  //it does not block the current thread and will return before completion of all its contents.
 //As well, this is executed on a concurrent queue, so the lines within will begin 
 //in the order they are shown however they may finish at any time
  print(1)
  print(2)
  print(3)
  print(4)
  //this could print the 4 numbers in ANY ORDER. Since it is called asynchronously it returns immediatley,
 //and does not block the current thread. And because the global_queue is a
 //concurrent queue, the numbers could print in any order
}


dispatch_sync(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.rawValue), 0)){
 //this will execute the tasks within synchronously, meaning that it WILL block the 
//current thread until the task is completed. It is dispatched to a concurrent queue, 
//therefore the tasks within will each begin in the order that they are read,
//however they may finish at any time
  print(1)
  print(2)
  print(3)
  print(4)
  //this could print 1,2,3,4 in ANY ORDER. This WILL block the current thread since 
 //it is called synchronously. However, since it is being called on a concurrent queue,
 //it could print the numbers in any order.
}

Are my assumptions correct? If not can you tell me where I am wrong and why? Thank you very much if you have taken the time to read this.

Upvotes: 1

Views: 95

Answers (1)

Sam R.
Sam R.

Reputation: 694

You got almost everything correct, with this notable exception:

dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.rawValue), 0)){
    /*
     ...
     this is executed on a concurrent queue, so the lines within will begin 
     in the order they are shown however they may finish at any time
     ...
     this could print the 4 numbers in ANY ORDER.
     ...
     because the global_queue is a
     concurrent queue, the numbers could print in any order
    */
}

Your understanding of the asynchronous aspect is correct; the async calls return immediately without blocking the thread they are called from. However, the concurrency of the dispatched routine is not in regards to amongst instructions within that routine. Note that closures are essentially just functions which capture their scope, so there is no unique behavior involved with the execution of their contents.

Instead, the concurrency occurs amongst multiple routines (i.e. multiple closures) dispatched to the concurrent queue. Take the following:

// These routines are executed asynchronously to the current thread, and
// serially to one another; the results will always be 1 through 4.
let serialQueue = dispatch_get_main_queue()
dispatch_async(serialQueue) { print(1) }
dispatch_async(serialQueue) { print(2) }
dispatch_async(serialQueue) { print(3) }
dispatch_async(serialQueue) { print(4) }

// These routines are executed asynchronously to the current thread, and
// concurrently to one another; they will print out in an undefined order.
let concurrentQueue = dispatch_get_global_queue(Int(QOS_CLASS_UTILITY.rawValue), 0)
dispatch_async(concurrentQueue) { print(1) }
dispatch_async(concurrentQueue) { print(2) }
dispatch_async(concurrentQueue) { print(3) }
dispatch_async(concurrentQueue) { print(4) }

Upvotes: 2

Related Questions