如何在UITableViewCell中正确处理异步任务?

时间:2016-03-22 12:45:36

标签: ios objective-c iphone uitableview

在UITableView中重用单元格存在问题: 假设我在单元格中有一个http请求,可能需要大约20秒才能执行。它的完成块影响细胞外观。用户可能希望此时滚动表视图(请求正在执行时)。请求执行后,完成块将不会影响正确的单元格,因为在tableview滚动时会重复使用单元格。

此外,如果您只是在完成块中检查单元格是否正确(例如通过标记每个单元格并检查它是否相同),当您向后滚动时,您将看不到单元格外观的更改到适当的细胞。 你对这个问题有一个优雅的解决方案吗?

这是我的代码的简化示例,它有这个问题。它是单元格中按钮的IBAction方法,可以通过setInviteStatus方法更改单元格

- (void)setInviteStatus:(INVITE_STATUS)status withOldTag:(NSInteger)oldTag {//old tag is to change only if cell is related to the invitation, because tableView reuses cells
  if (self.tag != oldTag)
    return;
  switch (status) {
    case INVITE_STATUS_ACCEPTED:
      [self.btnInvite setTitle:@"Accepted" forState:UIControlStateNormal];
      break;

    case INVITE_STATUS_INVITE:
      [self.btnInvite setUserInteractionEnabled:YES];
      [self.btnInvite setTitle:@"Invite" forState:UIControlStateNormal];
      break;

    case INVITE_STATUS_REJECTED:
      [self.btnInvite setTitle:@"Rejected" forState:UIControlStateNormal];
      break;

    default:
      break;
  }
}

- (IBAction)invitePressed:(UIButton *)sender {
    NSInteger tag = self.tag; //to save it, it might change due to cell reusing
    [[JLAccountManager sharedManager] inviteUser:tag withCompletion:^(NSDictionary *response, NSError *error) {
      if ([response[ResponseAnswer] isEqual: @YES]) {
        [self setInviteStatus:INVITE_STATUS_ACCEPTED withOldTag:tag];
      } else {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
          [self setInviteStatus:INVITE_STATUS_INVITE withOldTag:tag];
        });
        [self setInviteStatus:INVITE_STATUS_REJECTED withOldTag:tag];
      }
    }];
}

0 个答案:

没有答案
相关问题