setImage:forState:滞后于UI

时间:2012-10-23 23:51:47

标签: objective-c ios multithreading uiimage grand-central-dispatch

我有一个tableview,它运行一些代码,用于在后台线程中从NSData获取UIImage,然后在前台调用[button setImage:image forState:UIControlStateNormal];

问题是它在该行上暂停了一秒钟的UI,直到它完成。这意味着UI在将其设置为图像时会冻结。因为用户正在滚动,所以这是非常明显和紧张。有没有办法避免我的UI像这样冻结?

dispatch_queue_t cellSetupQueue = dispatch_queue_create("Setup", NULL);
dispatch_async(cellSetupQueue, ^{
    UIImage *image = [self.mediaDelegate largeThumbnailForMediaAtIndex:indexPath.row];
    dispatch_async(dispatch_get_main_queue(), ^{     
        [self.thumbnailButton setImage:image forState:UIControlStateNormal];
    });
});

dispatch_release(cellSetupQueue);

1 个答案:

答案 0 :(得分:3)

我猜你的图片是JPG。如果是这样,那么UIImage将推迟解码实际图像,直到它第一次实际需要这些像素为止。查看ImageIO框架以获得更精确的控制。这是我使用的片段:

CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); // data is your image file NSData
if (source)
{
    NSDictionary *dict = @{ (__bridge NSString *)kCGImageSourceShouldCache : @(YES) };
    CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (__bridge CFDictionaryRef)dict);
    if (cgImage)
    {
        CFRelease(source);
        return cgImage; // you can keep this reference so you dont have to decode again later
    }
}

重要的部分是kCGImageSourceShouldCache选项。您可以在后台线程上运行此代码,并将解码后的图像传递给UI线程。