iOS:在调用 reloadRowsAtIndexPaths 时,didEndDisplayingCell 被调用两次

标签 ios objective-c uitableview firebase firebase-realtime-database

每当我调用 reloadRowsAtIndexPaths 时; didEndDisplayingCell 方法被调用了两次。为什么会这样?

我实现了以下 UITableViewDelegate 和 UITableViewDataSource 的委托(delegate)方法:

  • - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

  • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

  • - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath

我之所以实现 didEndDisplayingCell 是因为我想分离 Firebase 监听器。

这是我在里面实现的 didEndDisplayingCell

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath{
// detach the listener for the cell at path index indexPath

  CustomCell* customCell = (CustomCell*)(cell);
  [customCell detachListener]; 
}

每当单元格监听更新的数据时,它都会在 ViewController 中触发一个方法,该方法会重新加载 tableViewCell。以下是我如何实现该方法:

-(void)refreshCellWithIndexPath:(NSIndexPath*) indexPath andData:(CustomData*)data{

  [self.dataArray replaceObjectAtIndex:indexPath.row withObject:data];

  [self.tableView beginUpdates];
  [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
  [self.tableView endUpdates];
}

当此方法执行时,UITableView 委托(delegate)方法将按照以下顺序调用:

  1. numberOfRowsInSection
  2. cellForRowAtIndexPath
  3. didEndDisplayingCell
  4. didEndDisplayingCell

为什么这个 didEndDisplayingCell 方法被调用了第二次? 请帮我解决这个问题。

最佳答案

可能的解决方法:

代替

[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

使用(快速):

reloadCounter += 1
CATransaction.begin()
tableView.beginUpdates()
CATransaction.setCompletionBlock {
    self.reloadCounter -= 1
}
tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .none)
tableView.endUpdates()
CATransaction.commit()

reloadCounter 是一个 ivar。

并在 didEndDisplaying 中:

func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if (reloadCounter == 0) {
        self.output.didEndDisplaying(viewModel: dataProvider.items[indexPath.row])
    }
}

关于iOS:在调用 reloadRowsAtIndexPaths 时,didEndDisplayingCell 被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44788055/

相关文章:

ios - Parse.com 自定义单元格 boolean 值

objective-c - 删除分组 UITableView 部分之间的空格

swift - 如果在 TableView didSelectRowAtIndexPath 函数中选择了其他行,如何将图像更改为以前的状态?

ios - 在 Swift 4 中根据 Table View 高度动态调整布局

ios - 写 CBCharacteristic 的问题

ios - Swift Spritekit - 如果已经添加了相同的 Sprite ,则将其添加到场景时会出现问题

ios - 调试 Swift 代码时,我能否仅根据对象的地址获得对象的类型化引用?

objective-c - NSScrollView 剪辑文档 View 而不是允许它滚动

ios - 音频检测器可以在设备上工作,但不能在模拟器上工作......和准确性

objective-c - 限制后台线程的 CPU 使用率