dispatch_get_global_queue vs dispatch_get_main_queue

tra*_*uan 42 objective-c grand-central-dispatch ios

开始学习核心数据和dispatch_async.有一段代码可以从数据集中获取图像的url,并将其设置为核心数据的模型,如下所示

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
                NSString *urlString = [[[photoDictionary valueForKey:@"images"] objectAtIndex:0] valueForKey:@"url"];
                NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [photoModel setValue:imageData forKey:@"photoImageData"];
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释为什么我们使用dispatch_get_global_queue外部dispatch_async和dispatch_get_main_queue内部dispatch_async.

Rob*_*Rob 85

dispatch_get_global_queue让你一个后台队列时,你可以派遣被异步运行后台任务(即不会阻止你的用户界面).如果您最终向全局队列提交多个块,则这些作业可以同时运行.如果您有多个代码块要提交到后台必须在后台运行的后台队列(通常不需要),您可以创建自己的串行后台队列并调度到该队列,但是如果并发后台操作是可以接受,然后利用自己的dispatch_get_global_queue方便/高效.

要知道,虽然,你不能在后台执行队列中的用户界面的更新,所以dispatch_asyncdispatch_get_main_queue让这样的背景下队列调度用户界面更新回到主队列,一旦主队列是可用的.

这是一种非常常见的编程模式:提交在后台运行的内容以及何时需要执行用户更新,将更新分发回主队列.

有关更多信息,请参阅" 并发编程指南".

  • 还有一点需要注意:不建议在全局队列上阻塞IO,因为全局队列的线程限制非常低(64个线程).一旦所有可用线程在IO上被阻止,*程序中其他任何工作,包括使用全局队列的系统框架*中的任何工作都将停止. (17认同)

age*_*ped 15

dispatch_get_main_queue应随时使用要操纵UI元素.这与线程关联性有关,线程关联性是UI框架的通用模型.线程关联意味着您只能操作创建该对象的线程上的对象.对于Cocoa Touch中的UI类,这是主线程.这是所有平台上UI框架的典型习惯.

因此dispatch_get_main_queue获取与主线程关联的队列.当你的UI在不同的线程上更新时,不这样做会导致奇怪的事情发生.我通常会看到UI暂停的长时间停顿.

dispatch_get_global_queue获取与您的应用关联的给定优先级的任何旧队列.非常适合网络呼叫,或者像在您的情况下使用Core Data一样.


ger*_*iam 9

全局队列为您提供除主要队列之外的队列,但为您节省了实际创建自己的队列的麻烦.当您需要代码在主队列上工作时(需要执行所有UI工作),请使用get_main_queue