UITableViewCell图像异步队列缓存无法正常工作

时间:2014-01-31 22:40:26

标签: ios objective-c uitableview caching asynchronous

任何人都可以告诉我我的代码有什么问题。它似乎工作,但当我快速滚动然后停止时,UIImageView循环显示几张图片,然后显示正确的一张。这很快发生但很明显。

if (![post objectForKey:@"photoData"] && ![post objectForKey:@"isDownloadingPhoto"]){
    cell.instagramPhoto.image = nil;
    [[combinedArray objectAtIndex:indexPath.row] setObject:@"loading" forKey:@"photoData"];
    [[combinedArray objectAtIndex:indexPath.row] setObject:@"yes" forKey:@"isDownloadingPhoto"];
    [cell.instagramPhoto setAlpha:0];
    if (instagramURL != nil){
        dispatch_async(kBgQueue, ^{
            int index = indexPath.row;
            NSData* data = [NSData dataWithContentsOfURL: instagramURL];
            if (data.length > 0){
                [[combinedArray objectAtIndex:index] setObject:data forKey:@"photoData"];
                [[combinedArray objectAtIndex:index] setObject:@"no" forKey:@"isDownloadingPhoto"];
                UIImage *image = [UIImage imageWithData:data];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    cell.instagramPhoto.image = image;
                    [UIView beginAnimations:nil context:NULL];
                    [UIView setAnimationBeginsFromCurrentState:YES];
                    [UIView setAnimationDuration:0.4f];
                    cell.instagramPhoto.alpha = 1.0;
                    [UIView commitAnimations];
                });
            }
        });
    }
}
else if ([[post valueForKey:@"isDownloadingPhoto"] isEqualToString:@"yes"]) {
    NSLog(@"loading");
    cell.instagramPhoto.image = nil;
}
else {
    NSData *data = [post valueForKey:@"photoData"];
    NSLog(@"saved");
    UIImage *image = [UIImage imageWithData:data];
    cell.instagramPhoto.image = image;
}

1 个答案:

答案 0 :(得分:-1)

看起来此代码在tableView:cellForRowAtIndexPath内执行。如果您在此处有任何单元重用逻辑 - 在完成对此单元的当前异步映像下载操作之前,单元将被重用时可能会出现问题。

如果在完成单元格之前重新使用单元格,则需要能够中止这些下载任务。

**更新**

有几种方法可以实现它:

  • 最简单的(并且可能耗费大量内存) - 确保为每个单元格生成唯一的cellId,因此不会重复使用已分配的单元格。它会慢一点,但你可以保证你开始的操作将在你启动它的同一个单元格上完成。

  • 下载完成后检查该单元格是否相同。例如,您可以在代码的开头为单元格分配tag到其行号。

    cell.tag = indexPath.row

然后在开始dataWithContext通话之前将其保存,并在之后检查。

int oldTag = cell.tag;
dataWithContext...
if (cell.tag != oldTag) {
   // Don't so any image update
}
  • 将dataWithContext更改为异步,以便您可以实际中断和中止下载过程。我不确定如何继续这个 - 它需要更多的研究。