【问题标题】:Calling numberOfRowsInSection: from heightForRowAtIndexPath调用 numberOfRowsInSection:来自 heightForRowAtIndexPath
【发布时间】:2015-07-31 04:50:51
【问题描述】:

刚刚在 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 框架中的错误?

【问题讨论】:

  • 好像是苹果内部的处理方式。我想我们需要一位 Apple 工程师来回答这个问题。
  • 不应该是浮点数 44.0 和 88.0 吗?
  • 也许这样在技术上会更有效,提前告诉编译器它是一个浮点数......但我无法想象它的性能差异很大;我拥有的任何最后都会有一个点 0 的浮点数都是这样写的,我没有遇到任何问题......

标签: objective-c ios uitableview


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢!这是一个很好的观点......在我的脑海中,我不知道为什么我要求 numberOfRowsInSection,而不仅仅是使用我用来获取行数的相同模型信息...... .
猜你喜欢
  • 2015-09-08
  • 2013-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多