调用numberOfRowsInSection:从heightForRowAtIndexPath

刚刚在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的方法返回数据源值的caching版本,所以它需要第一次从数据源获取值。 但是,然后,它调用heightForRowAtIndexPath,再次传递indexPath [0,0]! 而且它不停止。

我能够通过使用来解决它

 [self tableView:tableView numberOfRowsInSection:indexPath.section] 

相反(调用我的数据源方法,而不是tableView的方法)。 任何人都知道为什么这样做? 这是定义的行为? 还是苹果的TableView框架中的错误?

问题是UITableView询问你的数据源的数据,你告诉它的答案取决于它可能或可能没有caching的数据。

你误解了苹果基于其控制的MVC布局。 行的高度的答案应该来自你的模型,而不是callback视图类。 这导致视图类要求更多的信息(build立其内部caching),这是开始一套recursion调用。

确保所有数据源委托方法都返回来自模型的数据,不要依赖视图caching任何东西。 如果你debugging任何基于数据源的视图,你会惊讶UITableView要求数据的次数。 但这是苹果公司编码的方式。