使用dispatch_async在UICollectionView中加载图像

时间:2015-07-13 23:48:14

标签: ios asynchronous uicollectionview grand-central-dispatch

我使用Parse来存储图像。我试图异步加载图像,因此它不会干扰collectionView滚动。我是新手使用dispatch_async,我不太确定如何正确实现它。我也考虑过懒惰的负载,但我认为这样可行。但它并没有,collectionView卷轴不稳定。感谢

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    albumImageCell *cell = (albumImageCell *) [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];

    if (cell == nil) {
        cell = [[albumImageCell alloc]init];
    }

    PFObject *temp = [_dataArray objectAtIndex:indexPath.row];
    PFFile *file = [temp objectForKey:@"image"];

    if (cell.hasImage == FALSE) {
        dispatch_async(imageQueue, ^{
            NSData *data = [file getData];
                if (data) {
                    dispatch_async(dispatch_get_main_queue(), ^(void){
                        cell.imageView.image = [UIImage imageWithData:data];
                        cell.hasImage = TRUE;
                    });

                }
        });
    }

    return cell;
} 

1 个答案:

答案 0 :(得分:1)

因为UIImage +imageWithData方法稍微阻塞了主线程。

dispatch_async(dispatch_get_main_queue(), ^(void){
    cell.imageView.image = [UIImage imageWithData:data];

所以这些行应如下所示。

UIImage *image = [UIImage imageWithData:data];

dispatch_async(dispatch_get_main_queue(), ^(void){
    cell.imageView.image = image;

此外,在实际显示或呈现UIImage对象之前,UIImage不会立即解码图像。见https://stackoverflow.com/a/19251240/629118。因此,以下代码是摆脱不稳定滚动的最佳方法之一。

UIImage *image = [UIImage imageWithData:data];

UIGraphicsBeginImageContext(CGSizeMake(1,1));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawImage(context, CGRectMake(0, 0, 1, 1), [image CGImage]);
UIGraphicsEndImageContext();

dispatch_async(dispatch_get_main_queue(), ^(void){
    cell.imageView.image = image;