首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >大中央调度和并发问题

大中央调度和并发问题
EN

Stack Overflow用户
提问于 2012-07-30 16:38:59
回答 7查看 1.3K关注 0票数 1

我有一个带有图像的表视图,该图像正在使用grand中央调度懒惰地加载。我使用了一个异步队列,里面有两个串行队列,第一个用于下载图像,第二个队列用于将图像设置到单元。此方法在滚动时似乎有滞后行为。

代码语言:javascript
运行
复制
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        __block UIImage *image = nil;
        dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:artist.imImage]]];
        });
        dispatch_sync(dispatch_get_main_queue(), ^{
            cell.artistImage.image = image;

        });

    });

然后我尝试用一个异步队列来下载图像,然后在里面获取主队列并设置图像。就连我也觉得这个方法不太合适。我想我在这里漏掉了什么。

代码语言:javascript
运行
复制
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:artist.imImage]]];
        dispatch_async(dispatch_get_main_queue(), ^{
            cell.artistImage.image = image;
        });

    });

我是不是遗漏了什么,或者是其他问题?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-07-30 16:46:34

UIKit不是线程安全的,所以您应该将所有UIKit操作排队到主队列中。目前还不清楚您在使用第二个解决方案时遇到了什么问题:

代码语言:javascript
运行
复制
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:artist.imImage]]];
    dispatch_async(dispatch_get_main_queue(), ^{
        cell.artistImage.image = image;
    });

但我建议在主线程中实例化UIImage:

代码语言:javascript
运行
复制
    NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:artist.imImage]];
    dispatch_async(dispatch_get_main_queue(), ^{
        UIImage *image = [UIImage imageWithData:data];
        cell.artistImage.image = image;
    });
票数 2
EN

Stack Overflow用户

发布于 2012-07-30 18:30:01

您拥有的第二个解决方案是前进的道路--创建超过必要的任务是没有意义的(当然,“必需”的值取决于您想要做什么)。

但是,您可能会看到一个问题:

单元格出现

  1. 您在GCD任务中请求图像
  2. 用户向上滚动
  3. 单元格得到重用<

>H19您在GCD任务中请求新图像

  1. 原始请求(来自步骤2)完成,并使用“旧”图像更新单元格

在使用图像进行更新之前,您需要检查单元格是否仍为“当前”。

票数 1
EN

Stack Overflow用户

发布于 2012-07-30 19:42:46

我这样做了,但我在实现中使用了NSOperationNSOperationQueue。当细胞离开屏幕时,它不再需要图像,因此它取消了异步download+expand NSOperation。队列的最大值非常低(也限制了内存需求)。调优后非常流畅(在服务器上的图像大小合适之后)。

如果不消耗大量的空间,也可以考虑缓存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11717953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档