如何在委托方法cellForRowAtIndexPath中调用的方法中在完成块中编辑UITableViewCell:

时间:2015-06-18 19:37:57

标签: ios objective-c uitableview

在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;
}

1 个答案:

答案 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]
             }
         }];

如果您决定在非主线程中运行异步请求,则需要在主线程上安排行重新加载。