Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling numberOfRowsInSection: from heightForRowAtIndexPath

Just found a very strange and unexpected behavior in the UITableView class. I need the last table cell in my section to be a different height from the other cells, so I'm doing basically this:

- (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
}

Seems pretty straight-forward, but when I run it, I get an infinite loop and it crashes. I determined that when I call numberOfRowsInSection:, it calls my datasource's tableView: numberOfRowsInSection: method. This makes sense as the tableView's method returns a cached version of the datasource value, so it needs to get the value from the datasource the first time. But then, it calls heightForRowAtIndexPath, passing it indexPath [0, 0] again! And it does this non-stop.

I was able to get around it by using

[self tableView:tableView numberOfRowsInSection:indexPath.section]

instead (calling my datasource method instead of the tableView's method). Anyone have any idea why it does this? Is this defined behavior? Or a bug in Apple's TableView framework?

like image 694
GendoIkari Avatar asked Dec 07 '10 21:12

GendoIkari


1 Answers

The problem is that the UITableView is asking your datasource for data, and you are telling it the answer depends on data it may or may not have cached.

You're misunderstanding the M-V-C layout that Apple bases its controls on. The answer to the height of a row should come from your model, NOT from a call back to the view class. This is causing the view class to ask for more information (to build its internal cache), which is starting a set of recursive calls.

Make sure all datasource delegate methods return data from your model and don't rely on the view caching anything. If you debug any datasource based view, you'll be surprised how many times a UITableView asks for data. But that's the way Apple coded it.

like image 111
Comrade Yeti Avatar answered Sep 17 '22 17:09

Comrade Yeti