2

我只是想确认为什么需要这样做。

我将此代码添加到 KIImagePager(一个 cocoapod)以加载应用程序本地的图像(默认代码从 url 加载图像)。

这是我根据同事建议的工作代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [imageView setImage:[UIImage imageNamed:[aImageUrls objectAtIndex:i]]];;
                });
            });

我注意到,如果我取出内部 dispatch_sync,它会起作用,但不会以我想要的方式工作(当我开始滚动时,图像寻呼机滚动视图上的一些图像尚未加载)。但它们最终会加载。

我的问题是,主队列上的同步调用是否将图像返回到 UI(在主队列上)?因为它确实适用于第二个异步删除。

4

2 回答 2

9

内部调度在主线程上执行其代码块。这是必需的,因为所有 UI 操作都必须在主线程上执行。并且您的图像下载代码(执行此代码段的上下文)可能位于后台线程上。

外部调度在后台线程上执行其块。它给定的块是在主线程上执行的块。因此,可以安全地移除外部块。

小时你正在使用的成语的大纲。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    // do blocking work here outside the main thread. 
    // ...
    // call back with result to update UI on main thread
    //
    // what is dispatch_sync? Sync will cause the calling thread to wait
    // until the bloc is executed. It is not usually needed unless the background
    // background thread wants to wait for a side effect from the main thread block
    dispatch_sync(dispatch_get_main_queue(), ^{
        // always update UI on main thread
    });
});
于 2013-06-08T19:20:09.327 回答
2

您应该只在主线程上使用 UI 对象。如果你不这样做,你会遇到几个问题。如您所见,第一个是 UI 对象将延迟更新。第二个是如果您尝试从多个线程同时更改 UI 对象,应用程序可能会崩溃。您应该只在主线程上使用 UI 对象。

于 2013-06-08T19:16:15.263 回答