在UITableView委托方法cellForRowAtIndexPath:(NSIndexPath *)indexPath中,我想为单元格imageView设置图像。如果图像不可用,我想下载它,然后在完整的块中异步设置它。问题是因为细胞是可重复使用的,所以当调用完成块时,细胞可能不再存在。 如何在调用完成块时更新单元格?或者这样好吗?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
FriendTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"Friend Cell"];
Friend *friend = self.friends[indexPath.row];
if (friend.picture) {
cell.userProfileImageView.image = [UIImage imageWithData:pictureData];
} else {
cell.userProfileImageView.image = nil;
NSURL *pictureURL = [NSURL URLWithString:[NSString stringWithFormat:@"https://graph.facebook.com/%@/picture?type=normal&return_ssl_res", friend.facebookId]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:pictureURL];
// Run network request asynchronously
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError == nil && data != nil) {
friend.picture = data;
FriendTableViewCell *cellToUpdate = (FriendTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
cellToUpdate.userProfileImageView.image = [UIImage imageWithData:data];
}
}];
}
return cell;
}
答案 0 :(得分:3)
在完成处理程序中,只需要求表重新加载受影响的行。由于您的数据模型现在具有图片,因此它将正确更新。这也可以防止细胞离开屏幕,从而导致noop()。当您向后滚动时,所有图片现在都在您的数据模型中。
类似于:
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (connectionError == nil && data != nil) {
friend.picture = data;
self.tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationNone]
}
}];
如果您决定在非主线程中运行异步请求,则需要在主线程上安排行重新加载。