46

开始学习核心数据和 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"];

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

4

5 回答 5

91

(在 Swift 中) 为您提供了一个后台队列,您可以在该队列上调度异步运行的后台任务dispatch_get_global_queueDispatchQueue.global()即不会阻塞您的用户界面)。如果您最终将多个块提交到全局队列,这些作业可以同时运行。如果您有多个代码块要提交到必须在后台按顺序运行的后台队列(不经常需要),您可以创建自己的串行后台队列并分派到该队列,但如果并发后台操作是可以接受,然后利用自己dispatch_get_global_queue是方便/有效的。

但是请注意,您不允许在后台队列中执行用户界面更新,因此一旦主队列被取消dispatch_asyncdispatch_get_main_queue(即DispatchQueue.main.async { ... }在 Swift 中)该后台队列可以将用户界面更新分派回主队列可用的。

这是一种非常常见的编程模式:提交一些东西在后台运行,当它需要执行用户更新时,将更新分派回主队列。

有关详细信息,请参阅并发编程指南

于 2012-10-02T15:28:51.387 回答
15

dispatch_get_main_queue应该在您想要操作 UI 元素的任何时候使用。这与线程亲和性有关,这是 UI 框架的常见模型。线程关联意味着您只能在创建该对象的线程上操作该对象。对于 Cocoa Touch 中的 UI 类,这是主线程。这是所有重要平台上 UI 框架的典型习惯用法。

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

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

于 2012-10-02T15:25:59.360 回答
9

全局队列为您提供主队列以外的队列,但省去了实际创建自己的队列的麻烦。当你需要你的代码在主队列上工作时使用 get_main_queue(你所有的 UI 工作都需要在这里进行)

于 2012-10-02T15:19:10.533 回答
2
**dispatch_get_main_queue** :- Perform UI updates on this queue

 dispatch_async(dispatch_get_main_queue(), ^{


self.label.text=@"Hello";

    });

**dispatch_get_main_queue**:- Perform background tasks like downloading content

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    for (int i=0; i<100000;enter code here i++) {
        NSLog(@"HIGH 1 %d", i);
    }
});
于 2017-01-05T14:22:29.017 回答
0

简而言之,dispatch_get_global_queue是用来执行后台任务的。但是,当您在后台执行任何任务时,如果您需要执行任何与 相关的任务user interface,则需要在dispatch_get_main_queue()

于 2020-12-27T08:52:43.657 回答