我对这段代码有疑问
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
kLatestKivaLoansURL];
[self performSelectorOnMainThread:@selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
这段代码的第一个参数是
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
我们是否要求此代码在其定义本身是返回给定优先级的全局并发队列的全局队列上执行串行任务?
与主队列相比,使用 dispatch_get_global_queue
有什么优势?
我很困惑。您能否帮助我更好地理解这一点。
dispatch_queue_t myQueue
的变量类型中保护您的 dispatch_get_global_queue
。仅将 myQueue 传递给您的“dispatch_async”更具可读性
在主队列上使用默认队列的主要原因是在后台运行任务。
例如,如果我正在从 Internet 下载文件并且我想更新用户的下载进度,我将在优先级默认队列中运行下载并异步更新主队列中的 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
});
});
所有 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(即您将最后 250 个任务安排在 HIGH 队列上),很可能您看到的第一个任务将在该 HIGH 队列中,因为系统已经暗示这些任务需要尽快到达 CPU。
另请注意,我说“将按顺序开始执行”,但请记住,作为并发队列,事情不一定会根据每个任务的时间长度按顺序完成执行。
根据苹果:
当您有多个可以并行运行的任务时,并发调度队列很有用。并发队列仍然是队列,因为它以先进先出的顺序出列任务;但是,并发队列可能会在任何先前的任务完成之前使其他任务出队。并发队列在任何给定时刻执行的实际任务数量是可变的,并且可以随着应用程序中条件的变化而动态变化。许多因素会影响并发队列执行的任务数量,包括可用内核的数量、其他进程正在完成的工作量以及其他串行调度队列中任务的数量和优先级。
基本上,如果您将这 1000 个 dispatch_async() 块发送到 DEFAULT、HIGH、LOW 或背景队列,它们都将按照您发送它们的顺序开始执行。但是,较短的任务可能会在较长的任务之前完成。这背后的原因是是否有可用的 CPU 内核,或者当前队列任务是否正在执行计算非密集型工作(从而使系统认为它可以并行调度其他任务而不管内核数量如何)。
并发级别完全由系统处理,并基于系统负载和其他内部确定的因素。这就是 Grand Central Dispatch(dispatch_async() 系统)的美妙之处——您只需将工作单元作为代码块,为它们设置优先级(基于您选择的队列),然后让系统处理其余的。
所以回答你上面的问题:你是部分正确的。您正在“要求该代码”以指定的优先级在全局并发队列上执行并发任务。块中的代码将在后台执行,并且任何其他(类似)代码将可能并行执行,具体取决于系统对可用资源的评估。
另一方面,“主”队列(来自 dispatch_get_main_queue())是一个串行队列(不是并发的)。发送到主队列的任务将始终按顺序执行,并且始终按顺序完成。这些任务也将在 UI 线程上执行,因此它适用于使用进度消息、完成通知等更新您的 UI。
斯威夫特版本
这是 David 的 Objective-C 答案的 Swift 版本。您使用全局队列在后台运行事物并使用主队列来更新 UI。
DispatchQueue.global(qos: .background).async {
// Background Thread
DispatchQueue.main.async {
// Run UI Updates
}
}
不定期副业成功案例分享
0
表示什么?flags
参数,目前绝对没有任何作用。来自文档:Flags that are reserved for future use. Always specify 0 for this parameter.