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



任何人都可以告诉我我的代码怎么了。它似乎有效,但是当我快速滚动然后停止时,在显示正确的图片之前,请通过几张图片进行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;
}

看起来此代码是在tableView:cellForRowAtIndexPath中执行的。而且,如果您在这里有任何单元重复使用逻辑 - 您可能会在当前的异步下载操作完成此单元格之前重复使用单元格时遇到问题。

,如果要在完成之前重复使用细胞,则需要能够中止这些下载任务。

**更新**

有几种方法可以实施:

  • 最简单的一个(也许是最耗费最多的内存) - 确保您为每个单元格生成独特的牢房,因此不会重复使用已经分配的单元格。它会慢,但是您可以保证您开始的操作将在您启动的同一单元格上完成。

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

    cell.tag = indexpath.Row

然后在开始dataWithContext打电话之前保存下来并在后检查。

int oldTag = cell.tag;
dataWithContext...
if (cell.tag != oldTag) {
   // Don't so any image update
}
  • 将DataWithContext更改为Async,以便您实际上可以打破并中止下载过程。我不确定该如何进行这项工作 - 这需要更多的研究。

最新更新