ios - UITableView 异步 UIImage 设置

标签 ios objective-c asynchronous uitableview

我的目标是设置文本,然后对图像进行异步调用,并在到达时设置图像。

我目前正在异步调用要在 UITableViewCell 中设置的图像,并注意到我之前的技术导致了一个我最近发现的循环:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = [_tableView dequeueReusableCellWithIdentifier:@"id"];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
    }

    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:userAvatar]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (data) {
            UIImage* avatarImage = [UIImage imageWithData:data];
            if (avatarImage) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    [cell.imageView setImage:avatarImage];
                });


                /*
                 .--.      [STOP]
          .----'   '--.    |
          '-()-----()-'    |

          If I include the following, 
          the program goes in a loop, 
          and have not readily identified workaround:

                dispatch_async(dispatch_get_main_queue(), ^{
                    [_tableView reloadData];
                });

                           [GO]           .--.  
                           |         .----'   '--. 
                           |         '-()-----()-' 

                */
            }
        }
    }];

    cell.textLabel.text = @"foo";
    cell.detailTextLabel.text = @"bar";
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;


    return cell;
}

是否有一种方法可以在自定义类中没有自定义 setter 的情况下产生我正在寻找的结果?

最佳答案

你肯定不想在每次加载图像时都调用 -reloadData,它太重量级了,而且还会导致重新加载所有单元格,调用此方法,因为你我们发现了。

我完全不清楚您为什么要调用 -reloadData,因为这应该已经按原样工作了——在单元格的 imageView 上设置图像会导致显示刷新。 ..除了:

此代码中存在一个很大的逻辑错误,因为单元格一直在重复使用,但您是异步加载图像,然后将其设置为特定单元格。无法保证在图像加载时该单元格仍会分配到表格的同一行 - 您只是在此时将图像设置在随机单元格上。

一般来说,tableViews 只创建足够的单元格,可以同时在屏幕上显示,而不是每行一个表格。当您向下滚动表格时,顶部的单元格将被删除并在下方重新使用,以节省内存和创建时间。

不是直接在单元格上设置图像,而是在 tableView 中按行再次查找单元格(如果它仍然可见)并按此方式设置。

此外,您没有缓存您获取的图像,这将导致每次用户向下滚动然后再次向上滚动时获取新的图像。虽然内置的网络代码会做一定程度的缓存,但你永远不知道它有多少,而且将 HTTP 请求更改为完整图像肯定不会很快,所以你想自己缓存这些图像,与原始 URL 或行或唯一标识它们的任何键相关联。

关于ios - UITableView 异步 UIImage 设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21507359/

相关文章:

objective-c - 使用另一个项目的 Storyboard

javascript - JS Async/Await 不能与 forEach 结合使用

java - Spring 4在异步任务完成时更改jsp

python - Python 中的异步 PureMVC

iphone - iOS:如何执行 HTTP POST 请求?

iOS NSFileManager 使用 URL 而不是路径将文件存储在文档目录中?

ios - 显示带有完整文本的 UILabel 或隐藏它

iphone - Xcode/Obj-c - Segue 推送新实例

objective-c - iTunes 文件共享应用 : realtime monitoring for incoming datas

objective-c - Twitter JSON API的NSDate格式化程序问题