Well till a couple of days back I use to code everything for UITableViewCell
in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAt
Probably because we think customizing the properties and content of a cell belongs in a separate procedure from looking for a reusable cell to dequeue, and/or making a new one if there's nothing to dequeue.
[self configureCell:cell atIndexPath:indexPath];
it is simply just there to make your code clean and easy to read.
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
you can call it anything but the majority choose to call it this way. This is because this method got pass in UITableViewCell object and indexPath object then it return the "configed" UITableViewCell which is then get return as a return object for
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
in otherword, you can use
- (void)configureCellXXX:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
and call it using
[self configureCellXXX:cell atIndexPath:indexPath];
and it would still work :)
The only time that I've seen a real advantage, readability wise, is when you have multiple cell types. Then you can have separate methods that only know how to populate that particular cell type, like if you had 3 different cell types, for Dogs, Cats and Giraffes:
- (void)configureDogCell:(DogCell *)cell atIndexPath:(NSIndexPath *)indexPath
- (void)configureCatCell:(CatCell *)cell atIndexPath:(NSIndexPath *)indexPath
- (void)configureGiraffeCell:(GiraffeCell *)cell atIndexPath:(NSIndexPath *)indexPath
That said, I don't use this pattern myself. I've just seen it used by other developers in projects that I've worked on.
It's done because you may want to update cells when they're already on the screen. Rather than completely refreshing the cell, you can simply fetch the existing cell from the table view and run it through configureCell:atIndexPath:
. If the method is correctly implemented, this will update all the data in the cell without having UITableView remove the old cell, dequeue or allocate the new cell, and put it on screen.
For historical interest:
As far as I know, I'm the guy who's responsible for configureCell:atIndexPath:
. I'm sure other people have come up with the same idea, but I believe the snippet of code that popularized it was originally written by me. It was then spread by Apple and became a convention.
The early versions of NSFetchedResultsControllerDelegate
had a controllerDidChangeContent:
method, but no controllerWillChangeContent:
call, which meant there was no opportunity to call -[UITableView beginUpdates]
before changing the contents of the table view.
I filed Radar #6708453 asking for them to add this delegate method, and included some example code to show them what I wanted to do. That code had the actual cell updating logic in a refreshCell:atIndexPath:
call, so that it could be called from both tableView:cellForRowAtIndexPath:
and controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
.
When the next beta seed came out, I found that the iOS engineering team not only added the method I suggested, but copied the sample code from my bug report into the NSFetchedResultsControllerDelegate documentation, although they wisely changed the name to the less confusing configureCell:atIndexPath:
.
I actually started a new project today with the Master/Detail iOS Core Data template, and noticed that my code—and the configureCell:atIndexPath:
method with it—was in the template. I ran a quick Google search to see if it had become a common convention. It seems that it has. I'm rather proud of what that little chunk of code has made of itself!