为什么异步加载图像需要永远?

时间:2015-11-09 21:46:11

标签: ios objective-c asynchronous uicollectionview

我有一个显示一堆图像的UICollectionView。如果我不异步加载图像,则滚动非常不连贯并且提供差的用户体验。当我异步加载图像时,滚动是平滑的,但加载每个图像需要5到10秒。

为什么在后台加载图像时需要这么长时间?这是我在cellForItemAtIndexPath委托中的后台线程的代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImageView *bg = (id)self.backgroundView;
    UIImageView *selbg = (id)self.selectedBackgroundView;

    if (![bg isKindOfClass:[UIImageView class]])
        bg = [[UIImageView alloc] initWithImage:thumb];
    else
        [bg setImage:thumb];

    if (![selbg isKindOfClass:[UIImageView class]]){
        selbg = [[UIImageView alloc] initWithImage:thumb];
        coloroverlay = [[UIView alloc] initWithFrame:selbg.bounds];
        [coloroverlay setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
        [selbg addSubview:coloroverlay];
    } else
        [selbg setImage:thumb];

    [bg setContentMode:UIViewContentModeScaleAspectFill];
    [bg setTag: 1];
    [coloroverlay setBackgroundColor:[col colorWithAlphaComponent:0.33f]];
    [selbg setContentMode:UIViewContentModeScaleAspectFill];

    dispatch_sync(dispatch_get_main_queue(), ^{
        [self setBackgroundView:bg];
        [self setSelectedBackgroundView:selbg];
    });
});
编辑:正如@geraldWilliam指出的那样,我不应该从辅助线程访问视图。这是我更新了我的代码并解决了设置到错误单元格的图像问题:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImageView *bg = (id)self.backgroundView;
    UIImageView *selbg = (id)self.selectedBackgroundView;

    if (![bg isKindOfClass:[UIImageView class]]) bg = [[UIImageView alloc] initWithImage:thumb];

    if (![selbg isKindOfClass:[UIImageView class]]){
        selbg = [[UIImageView alloc] initWithImage:thumb];
        coloroverlay = [[UIView alloc] initWithFrame:selbg.bounds];
        [coloroverlay setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
        [selbg addSubview:coloroverlay];
    }


    dispatch_sync(dispatch_get_main_queue(), ^{
        [bg setImage:thumb];
        [selbg setImage:thumb];

        [bg setContentMode:UIViewContentModeScaleAspectFill];
        [bg setTag: 1];
        [coloroverlay setBackgroundColor:[col colorWithAlphaComponent:0.33f]];
        [selbg setContentMode:UIViewContentModeScaleAspectFill];

        [self setBackgroundView:bg];
        [self setSelectedBackgroundView:selbg];
    });
});

2 个答案:

答案 0 :(得分:3)

这里的大多数代码都适用于主队列。图像的加载应该在全局队列中,但其余部分,尤其是设置图像视图的图像,应该在主队列上。您的代码中发生的事情是,您将调度回主队列以设置背景视图,但在背景中保留图像属性的分配。所以,试试类似:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:myImageURL]];
  dispatch_sync(dispatch_get_main_queue(), ^{
    imageView.image = image;
    [self setBackgroundView:imageView];
  });
});

答案 1 :(得分:0)

我强烈建议您观看WWDC 2012 Session 211: Building Concurrent User Interfaces on iOS,这是有史以来最好的WWDC会话。它充满了清晰呈现的实用建议。

从主队列中删除UIImageView的东西令人担忧,应该修复,但可能不是导致缓慢的原因。你没有向我们展示thumb来自何处,这可能是缓慢的。