了解dispatch_async

use*_*873 230 asynchronous objective-c dispatch-async

我对此代码有疑问

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});
Run Code Online (Sandbox Code Playgroud)

这段代码的第一个参数是

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 
Run Code Online (Sandbox Code Playgroud)

我们是否要求此代码在全局队列上执行串行任务,其定义本身是返回给定优先级的全局并发队列?

使用dispatch_get_global_queue主队列有什么好处?

我很迷惑.你能帮我更好地理解这个吗?

Dav*_*vid 510

在主队列上使用默认队列的主要原因是在后台运行任务.

例如,如果我从互联网上下载文件并且我想更新用户下载的进度,我将在优先级默认队列中运行下载并异步更新主队列中的UI.

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //Background Thread
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates
    });
});
Run Code Online (Sandbox Code Playgroud)

  • @Honey 0是`flags`参数,目前绝对没有.来自文档:`保留供将来使用的标志.始终为此参数指定0 (3认同)
  • "0"表示什么? (2认同)

小智 197

所有DISPATCH_QUEUE_PRIORITY_X队列都是并发队列(意味着它们可以同时执行多个任务),并且在某种意义上,FIFO是指使用"先进先出"顺序开始执行给定队列中的任务.这与主队列(来自dispatch_get_main_queue())相比较,主队列是一个串行队列(任务将按照接收顺序开始执行并完成执行).

因此,如果向DISPATCH_QUEUE_PRIORITY_DEFAULT发送1000个dispatch_async()块,那么这些任务将按照您将它们发送到队列的顺序开始执行.同样适用于HIGH,LOW和BACKGROUND队列.您发送到任何这些队列的任何内容都将在后台执行,在远离主应用程序线程的备用线程上执行.因此,这些队列适用于执行后台下载,压缩,计算等任务.

请注意,执行顺序是基于每个队列的FIFO.因此,如果您将1000个dispatch_async()任务发送到四个不同的并发队列,均匀分割​​它们并按顺序将它们发送到BACKGROUND,LOW,DEFAULT和HIGH(即您在HIGH队列中安排最后250个任务),很可能是您看到的第一个任务将在HIGH队列中,因为系统已经暗示这些任务需要尽快到达CPU.

另请注意,我说"将按顺序开始执行",但请记住,作为并发队列,事物不一定按顺序执行,具体取决于每个任务的时间长度.

按照Apple:

https://developer.apple.com/library/content/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

当您有多个可以并行运行的任务时,并发调度队列非常有用.并发队列仍然是队列,因为它以先进先出顺序将任务队列化; 但是,并发队列可能会在任何先前任务完成之前将其他任务出列.并发队列在任何给定时刻执行的实际任务数是可变的,并且可以随着应用程序中的条件的变化而动态变化.许多因素会影响并发队列执行的任务数,包括可用核心数,其他进程正在完成的工作量以及其他串行调度队列中任务的数量和优先级.

基本上,如果您将这1000个dispatch_async()块发送到DEFAULT,HIGH,LOW或BACKGROUND队列,它们将按您发送的顺序开始执行.但是,较短的任务可能在较长的任务之前完成 这背后的原因是,如果有可用的CPU核心,或者当前队列任务正在执行计算上非密集型工作(从而使系统认为它可以并行分派其他任务,而不管核心数量).

并发级别完全由系统处理,并且基于系统负载和其他内部确定的因素.这是Grand Central Dispatch(dispatch_async()系统)的美妙之处 - 您只需将工作单元作为代码块,为它们设置优先级(基于您选择的队列),让系统处理其余部分.

所以回答你的上述问题:你是部分正确的.您"要求该代码"在指定优先级的全局并发队列上执行并发任务.块中的代码将在后台执行,任何其他(类似)代码将潜在并行执行,具体取决于系统对可用资源的评估.

另一方面,"main"队列(来自dispatch_get_main_queue())是一个串行队列(不是并发).发送到主队列的任务将始终按顺序执行,并始终按顺序完成.这些任务也将在UI线程上执行,因此它适用于使用进度消息,完成通知等更新UI.


Sur*_*gch 31

Swift版本

这是David的Objective-C答案的Swift版本.您使用全局队列在后台运行事物,并使用主队列来更新UI.

斯威夫特3

DispatchQueue.global(qos: .background).async {

    // Background Thread

    DispatchQueue.main.async {
        // Run UI Updates
    }
}
Run Code Online (Sandbox Code Playgroud)