Reputation: 1093
i have a tableview which has image and a text behind, i create the cells like below code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSDictionary * companyProductRow = [DB getCompanyProductRow:[self.companyProductIDs objectAtIndex:indexPath.row]];
int companyProductID = [[companyProductRow objectForKey:@"ID"] intValue];
cell.tag = companyProductID;
cell.textLabel.text = [companyProductRow objectForKey:@"ImagePath"];
NSString* fullPath = [FileManager fullPath:companyProductID fairDirectory:[[self.currentFair objectForKey:@"ID"]intValue]];
[[cell imageView] setImage:[UIImage imageWithContentsOfFile:fullPath]];
return cell;
}
i read some tips about tableview performance on apple developer site but all of they said is : Reuse cells. Object allocation has a performance cost, especially if the allocation has to happen repeatedly over a short period—say, when the user scrolls a table view. If you reuse cells instead of allocating new ones, you greatly enhance table-view performance. Avoid relayout of content. When reusing cells with custom subviews, refrain from laying out those subviews each time the table view requests a cell. Lay out the subviews once, when the cell is created. Use opaque subviews. When customizing table view cells, make the subviews of the cell opaque, not transparent.
the sample in apple site is the same, but i want to know is there any way to have better performance when scrolling on uitableview? (when we should read image from disk).
so thanks
Upvotes: 1
Views: 1573
Reputation: 5766
Yes it is.
The first thing you could enhance is the image loading.
Try to avoid [UIImage imageWithContentsOfFile:fullPath]
because it always loads the entirely image into the memory. This in fact is slow. Use [UIImage imageNamed:"YOUR_IMGAES_NAME"]
instead because it caches the images after the first use or preload/store them directly in your fileManager.
The next step would be to set all views in the cell to nil
(like the imageView) and draw all the contents by hand. The reason for this is that UIViews
are pretty slow. If you have a lot of labels, images, etc. to display it happens to be much faster to draw everything by hand.
Upvotes: 3
Reputation: 17500
Your tableView:cellForRowAtIndexPath:
looks like it's doing 2 disk reads for each cell, one from your [DB getCompanyProductRow:...]
which I assume is a database fetch of some sort, and the second from the [UIImage imageWithContentsOfFile:...]
.
Find a way to load these information to memory, before tableView:cellForRowAtIndexPath:
gets called (preferably before [tableview reloadData]
).
Tips for large datasets:
If the data you need to fetch is too big for the memory to be loaded into an array, try to implement some paging mechanism so you just need to display a subset of that data. I would even recommend you use Core Data's NSFetchedResultsController
instead, but that's if your database structure is compatible for object models.
Upvotes: 2