我的目标是设置文本,然后对图像进行异步调用,并在到达时设置图像。
我目前正在异步调用要在 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/