Whenever I scroll my tableview it is very laggy. I think it has to do with how I am loading up my cells. I use UINib (5.0+) whenever I can while still providing backwards compatibility. Then I load my custom cell’s labels and images with items from a NSDictionary from a NSArray which is loaded from NSUserDefaults in the ViewDidLoad.
Is there any way to improve the efficiency of this cellForRowAtIndexPath?
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell *)[aTableView dequeueReusableCellWithIdentifier:@"Cell"];
if (cell == nil) {
if ([self labelCellNib]) {
[[self labelCellNib] instantiateWithOwner:self options:nil];
} else {
[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
}
cell = [self CustomTableCell];
[self setCustomTableCell:nil];
}
NSDictionary *dictionary = [myArray objectAtIndex:indexPath.row];
NSData *data = [dictionary objectForKey:@"OCRImage"];
cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];
cell.titleLabel.text = [dictionary objectForKey:@"Title"];
cell.titleLabel.delegate = self;
cell.dateLabel.text = [dictionary objectForKey:@"Date"];
if (indexPath.row%2) {
cell.backgroundImage.image = firstImage;
}
else {
cell.backgroundImage.image = secondImage;
}
return cell;
}
Edit:
- (UIImage*)roundCorneredImage: (UIImage*)orig radius:(CGFloat) r {
UIGraphicsBeginImageContextWithOptions(orig.size, NO, 0);
[[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, orig.size}
cornerRadius:r] addClip];
[orig drawInRect:(CGRect){CGPointZero, orig.size}];
UIImage* result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}
Edit2: These are the lines that are causing the lag:
NSData *data = [dictionary objectForKey:@"OCRImage"];
cell.previewPicture.image = [self roundCorneredImage:[UIImage imageWithData:data] radius:60];
Some of my notes after looking at your code:
Is
roundCorneredImage:radius:caching the result? If not, executing CG calls for every cell would surely present a bottleneck. Updated: Use instruments to be sure, but it might be faster (memory allowing) to store the processedUIImagein a collection so that you can pull it out again the next time that method is called with the same parameters.All of your
UIImages could be declared elsewhere and then presented in this method. Your current code instantiates a newUIImagefor each cell which can also bottleneck your scrolling. Updated: SinceImage1.pngandImage2.pngare basically static, you could declare them in your interface or as a static ivar and then just assign them to the background image rather than instantiatingUIImageeach time.It may be faster to subclass
UITableViewCelland instantiate that instead of reaching intoUINib. Also, you’d then be able to separate your layout/data logic from the delegate method. Here’s a gist of what I did in myUITableViewCellsubclass. Basically, I store the entity with the cell and the cell knows about it’s labels and such. This keeps the cell layout logic out of my data source code.It looks like you’re using an
NSDictionaryas your data source. If you have a lot of objects in that dictionary, it may be considerable faster to useCoreDataand anNSFetchedResultsController. Here’s a good post on the matter. Updated: Ok, that shouldn’t be an issue.–
Edit
So if you removed all of this:
and it still lags, let’s look at your constructors…what do these lines do?
Also, you’re not using any transparent images or anything in your table cell are you? Those have been known to cause drawing lag…
–
Edit #2
If you strip down to this, what happens?