8

可能重复:
dispatch_get_global_queue 和 dispatch_queue_create 有什么区别?

我看到一些使用 gcd 的方法,但其中一些可能会这样做:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^{

    dispatch_sync(dispatch_get_main_queue(), ^{

    });
});

但其他人可能会这样做:

imageQueue_ = dispatch_queue_create("com.company.app.imageQueue", NULL);
dispatch_async(imageQueue_, ^{
        dispatch_async(dispatch_get_main_queue(), ^{

        });
    });

有什么区别?如果我想从网上下载很多图片,哪个更好?

4

2 回答 2

20

将队列概念化的最好方法是首先意识到在非常低的级别上,只有两种类型的队列:串行和并发。

串行队列是一夫一妻制的,但未提交。如果你给每个串行队列分配一堆任务,它将一次运行一个,一次只使用一个线程。未提交的方面是串行队列可能会在任务之间切换到不同的线程。串行队列总是在执行下一个任务之前等待一个任务完成。因此,任务按 FIFO 顺序完成。您可以根据需要创建任意数量的串行队列。

队列是一个特殊的串行队列。与其他未提交的串行队列不同,因为它们“约会”许多线程但一次只“约会”一个,主队列与主线程“结婚”并且所有任务都在其上执行。主队列与主线程的运行循环表现得很好,因此小操作不会阻塞 UI 和其他重要位。像所有串行队列一样,任务按 FIFO 顺序完成。

如果串行队列是一夫一妻制的,那么并发队列是混杂的。他们会将任务提交到任何可用的线程,甚至根据系统负载创建新线程。他们可以在不同的线程上同时执行多个任务。重要的是提交到全局队列的任务是线程安全的并尽量减少副作用。任务按 FIFO 顺序提交执行,但不保证完成顺序。

带回来,所有全局队列都是并发的,所有用户队列默认都是串行的,除非将其定义为并发。

如果您的目标是下载图像,您可能需要一个串行(用户)队列。下载图像更多的是带宽问题。您通常一次只想做一个(或几个)。

编辑:扩展上述答案的博客文章:http: //amattn.com/2013/08/28/grand_central_dispatch_gcd_summary_syntax_best_practices.html

于 2012-12-16T07:17:49.660 回答
3

如果您使用dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);GCD 将自动创建足够的线程来处理作业,并尽可能使用多个内核。

另一方面,如果你使用imageQueue_ = dispatch_queue_create("com.company.app.imageQueue", NULL);你会得到一个串行队列和先进先出行为。

如果您不担心线程安全或作业返回的顺序,请使用第一种方法。

于 2012-12-16T07:08:59.983 回答