调用numberOfRowsInSection:from heightForRowAtIndexPath

时间:2010-12-07 21:31:55

标签: objective-c ios uitableview

刚刚在UITableView类中发现了一个非常奇怪和意外的行为。我需要在我的部分中的最后一个表格单元格与其他单元格的高度不同,所以我基本上这样做:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == [tableView numberOfRowsInSection:indexPath.section] - 1)
        return 44;
    else
        return 88; //double size for all but the last row
}

看起来非常直接,但是当我运行它时,我得到一个无限循环而且它崩溃了。我确定当我调用numberOfRowsInSection:时,它会调用我的数据源的tableView: numberOfRowsInSection:方法。这是有道理的,因为tableView的方法返回数据源值的缓存版本,因此它需要第一次从数据源获取值。但是,它调用heightForRowAtIndexPath,再次传递indexPath [0,0]!它不停地做到这一点。

我能够通过使用

解决这个问题
[self tableView:tableView numberOfRowsInSection:indexPath.section]

代替(调用我的数据源方法而不是tableView的方法)。任何人都知道为什么会这样做?这是定义的行为吗?或Apple的TableView框架中的错误?

1 个答案:

答案 0 :(得分:17)

问题是UITableView正在向您的数据源询问数据,并且您告诉它答案取决于它可能或可能缓存的数据。

你误解了Apple基于其控制的M-V-C布局。行高的答案应该来自您的模型,而不是来自回调到视图类。这导致视图类要求提供更多信息(构建其内部缓存),这将启动一组递归调用。

确保所有数据源委托方法都从模型返回数据,并且不依赖于视图缓存任何内容。如果你调试任何基于数据源的视图,你会惊讶于UITableView要求数据的次数。但这就是Apple编码的方式。