Reputation: 1835
Time profiler shows the most time consuming operation in my app is loading UITableViewCells
from nib files. The most expensive of which involves loading a UITableViewCell
with a 4KB image.
I am loading the UITableViewCell
from the nib with the following code:
[[NSBundle mainBundle] loadNibNamed:@"UITableViewCellPortrait" owner:self options:NULL];
cell = portraitCell;
self.portraitCell = nil;
Has anyone compared the difference between creating a view programmatically or loading a UITableViewCell
from a nib?
EDIT:
I compared the time profile of repeated runs of loading the UITableViewCell
from a nib and creating the view programmatically. My test involved alternating between two UITableViews
about 10 times in the span of 3-5 seconds. In each test, loading the UITableViewCell
programmatically was substantially faster, between 2x to 6x faster.
Can anyone corroborate these results?
EDIT: I updated the nib loading code to only load the nib file once and use a cached version for subsequent calls.
if (self.UITableViewPortaitNib == nil) {
self.UITableViewPortaitNib = [UINib nibWithNibName:@"UITableViewCellPortrait" bundle:[NSBundle mainBundle]];
}
self.UITableViewPortaitNib instantiateWithOwner:self options:NULL];
cell = portraitCell;
self.portraitCell = nil;
I also used the automation instrument to create more consistent runs and the results still suggest loading UITableViewCells
programmatically is faster than loading UITableViewCells
for a nib. The average running time for loading UITableViewCells
from a nib was around 90ms, while the average running time for creating the UITableViewCell
programmatically was 50ms.
Upvotes: 15
Views: 4279
Reputation: 5891
In iOS 5 and mentioned in the WWDC 2011 videos, there is a newer method that uses UINib. You register your nib in your viewDidLoad:
method and then simplify the code in the tableView:cellForRowAtIndexPath:
method. This may speed things up for you (but I've never performed any comparison timings).
Example:
In your viewDidLoad:
register the nib and retain a reference to it:
NSString *myIdentifier = @"ReusableCustomCell";
[self.reuseCustomCell registerNib:[UINib nibWithNibName:@"ReusableCustomCell" bundle:nil] forCellReuseIdentifier:myIdentifier];
In your tableView:cellForRowAtIndexPath:
method just ask for the cell (no need to check for nil as it is guaranteed to return a cell under iOS5) and configure the cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *myIdentifier = @"ReusableCustomCell";
ReusableCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:myIdentifier];
// Your configuration code goes here
cell.nameLabel.text = @"some text";
// ....
return cell;
}
Code not tested. I'd be interested if this was any faster than using UINib alone.
Upvotes: 5
Reputation: 3181
It's possible to reuse the uitableviewcell nibs which are once loaded and then they go out of the view. Read the following:
iPhone - What are reuseIdentifiers (UITableViewCell)?
Upvotes: 0
Reputation: 36139
I load the nib cell (cellTemplate
) once and duplicate it as needed, so in a sense this approach is both programmatic and nib based.
Duplicating was more complicated than I expected as mutableCopy
didn't work. An NSKeyedArchiver
roundtrip did, however:
NSData* cellData = [NSKeyedArchiver archivedDataWithRootObject:cellTemplate];
cell = [NSKeyedUnarchiver unarchiveObjectWithData:cellData];
In fact if you're going for raw, blazing, pedal-to-the-metal speed, even the archived template can be calculated once and cached.
But shouldn't you be measuring frame rate? In that case the UIView's complexity comes into play too.
Upvotes: 2
Reputation: 385860
Try creating a UINib
object once and then sending it instantiateWithOwner:options:
each time you need to create a new cell. From the UINib Class Reference:
For example, if your table view uses a nib file to instantiate table view cells, caching the nib in a
UINib
object can provide a significant performance improvement.
Upvotes: 13