Grand Central Dispatch,不确定我是否完全理解这一点,这就是我如何使用它

时间:2016-02-01 05:24:16

标签: ios swift concurrency grand-central-dispatch synchronous

我正试图抓住Grand Central Dispatch的角色来改进我的代码的整体效率,但是,我并不完全确定如何使用它。下面是我目前(可能是可怕的误导)GCD假设的例子,基于教程以及许多其他堆栈溢出问题,一些快速博客和一些其他随机网站....

 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.
}

我的假设是否正确?如果没有,你能告诉我我错在哪里吗?为什么?非常感谢您花时间阅读本文。

1 个答案:

答案 0 :(得分:2)

几乎所有事情都是正确的,但有一个明显的例外:

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
    */
}

您对异步方面的理解是正确的; async调用立即返回而不阻塞调用它们的线程。但是,调度例程的并发与该例程中的指令无关。请注意,闭包基本上只是捕获其作用域的函数,因此其内容的执行不会涉及任何独特的行为。

相反,并发性发生在分派到并发队列的多个例程(即多个闭包)之间。请采取以下措施:

// 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) }