Reputation: 27485
I'm making an inventory app and have subclassed a grouped UITableView
that I made the background a UIImage that I set after initialization based in the location (top, middle, bottom, single). Then I set the detail image and text based on a cached array of categories and tools. The problem is that when stress tested (or tested at all) this runs very slow. Can anyone show me why this is running slow and/or give me some pointers to make it faster?
This is what it's supposed to look like:
Here's the code for the subclassed UITableViewCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
self.backgroundImage = [[[UIImageView alloc] initWithFrame:CGRectMake(-3, 0, 305.0f, 50)] autorelease];
self.roundedImageView = [[[UIImageView alloc] initWithFrame:CGRectMake(10, 8, 33, 33)] autorelease];
self.label = [[[UILabel alloc] initWithFrame:CGRectMake(50, 7, 140, 40)] autorelease];
self.topDes = [[[UILabel alloc] initWithFrame:CGRectMake(215, 5, 100, 15)] autorelease];
self.botDes = [[[UILabel alloc] initWithFrame:CGRectMake(215, 18, 100, 35)] autorelease];
self.midDes = [[[UILabel alloc] initWithFrame:CGRectMake(215.0f, 15.0f, 80.0f, 22.0f)] autorelease];
[self.contentView addSubview:self.backgroundImage];
[self.contentView addSubview:self.roundedImageView];
[self.contentView addSubview:self.label];
[self.contentView addSubview:self.topDes];
[self.contentView addSubview:self.midDes];
[self.contentView addSubview:self.botDes];
//Set properties for labels and images
[self prepareForReuse];
}
return self;
}
Here is the code for making the cells for the tableview
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (searching == NO) {
NSString *CellIdentifier = [NSString stringWithFormat:@"%d, %d", indexPath.section, indexPath.row];
OBcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[OBcell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
autorelease];
NSString *CellIdentifier = [NSString stringWithFormat:@"%d, %d", indexPath.section, indexPath.row];
OBcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[OBcell alloc]
initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
autorelease];
if (searching == NO) {
if (indexPath.row == 0) {
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {
cell.backgroundImage.image = singleTableImage;
} else {
cell.backgroundImage.image = topTableImage;
}
} else if (indexPath.row < [tableView numberOfRowsInSection:indexPath.section] - 1) {
cell.backgroundImage.image = middleTableImage;
} else {
cell.backgroundImage.image = bottomTableImage;
}
if (type == OBViewTypeTools) {
if ([[[[primaryArray objectAtIndex:indexPath.section] objectAtIndex:5] objectAtIndex:indexPath.row] integerValue] > 0) {
if (indexPath.row == 0) {
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {
cell.backgroundImage.image = singleTableImageRed;
} else {
cell.backgroundImage.image = topTableImageRed;
}
} else if (indexPath.row < [tableView numberOfRowsInSection:indexPath.section] - 1) {
cell.backgroundImage.image = middleTableImageRed;
} else {
cell.backgroundImage.image = bottomTableImageRed;
}
}
}
}
}
//Just pay attention to the cell.roundedImageView mainly, I'm thinking that's the problem unless you guys think it's something else...
switch (type) {
case OBViewTypeTools:;
cell.label.text = (NSString*)[[[primaryArray objectAtIndex:indexPath.section] objectAtIndex:2] objectAtIndex:indexPath.row];
cell.roundedImageView.image = [[[primaryArray objectAtIndex:indexPath.section] objectAtIndex:1] objectAtIndex:indexPath.row];
cell.topDes.text = [NSString stringWithFormat:@"Total: %d", [[[[primaryArray objectAtIndex:indexPath.section] objectAtIndex:3] objectAtIndex:indexPath.row] integerValue]];
cell.topDes.textColor = [UIColor yellowColor];
cell.topDes.font = smallFont;
cell.botDes.text = [NSString stringWithFormat:@"In Use: %d", [[[[primaryArray objectAtIndex:indexPath.section] objectAtIndex:4] objectAtIndex:indexPath.row] integerValue]];
cell.botDes.textColor = [UIColor blueColor];
cell.botDes.font = smallFont;
break;
case OBViewTypeCategories:;
ToolCategory *cat = (ToolCategory*)[primaryArray objectAtIndex:indexPath.row];
cell.label.text = cat.name;
cell.midDes.textColor = [UIColor lightGrayColor];
cell.midDes.font = smallFont;
cell.midDes.text = [NSString stringWithFormat:@"Tools: %d", [[cat tools] count] == 0 ? 0 : [[cat tools] count]];
cell.roundedImageView.image = cat.image;
break;
case OBViewTypeJobs:
cell.label.text = ((Job*)[primaryArray objectAtIndex:indexPath.row]).name;
cell.roundedImageView.image = ((Job*)[primaryArray objectAtIndex:indexPath.row]).image;
cell.midDes.text = [NSString stringWithFormat:@"Tools: %d", [((Job*)[primaryArray objectAtIndex:indexPath.row]).tools count]];
cell.midDes.font = smallFont;
cell.midDes.textColor = [UIColor lightGrayColor];
break;
case OBViewTypeJobTools:
cell.label.text = [((Tool*)[[[((ToolCategory*)[primaryArray objectAtIndex:indexPath.section]) tools] sortedArrayUsingDescriptors:sortDescriptors] objectAtIndex:indexPath.row]) name];
cell.roundedImageView.image = [((Tool*)[[[((ToolCategory*)[primaryArray objectAtIndex:indexPath.section]) tools] sortedArrayUsingDescriptors:sortDescriptors] objectAtIndex:indexPath.row]) image];
cell.midDes.text = [NSString stringWithFormat:@"(%d)", [[((ToolCategory*)[primaryArray objectAtIndex:indexPath.section]) tools] count]];
cell.midDes.font = smallFont;
case OBViewTypeToolJobs:
cell.label.text = [((Job*)[secondaryArray objectAtIndex:indexPath.row]) name];
cell.roundedImageView.image = [((Job*)[secondaryArray objectAtIndex:indexPath.row]) image];
cell.midDes.textColor = [UIColor blueColor];
cell.midDes.text = [NSString stringWithFormat:@"(%d)", [((Job*)[secondaryArray objectAtIndex:indexPath.row]) amountForTool:(Tool*)primaryObject]];
cell.midDes.font = smallFont;
break;
}
cell.clipsToBounds = NO;
cell.layer.masksToBounds = NO;
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Upvotes: 0
Views: 1088
Reputation: 18477
There are a number of potential issues going on with your setup including the following:
1) Your cell reuse identifier is very strange
NSString *CellIdentifier = [NSString stringWithFormat:@"%d, %d",
indexPath.section, indexPath.row];
The cell reuse identifer should be a static NSString that is used to deque like cells. Not reusing cells is very costly because new cells have to be instantiated, instead of reused. Looking at your example screenshot, all these cells are virtually the same, so you should use the same reuse identifier:
static NSString *CellIdentifier = @"InventoryItemCell";
2) You are using a lot of alpha transparency in your cells. In Core Animation, it takes extra processing power to blend alpha channels and transparency should be minimized as much as possible, especially in UITableView
. You can run the Core Animation Instrument to get a feel for how much alpha is being used in your app by turning on the Color Blended Layers debug option:
This will put on an overlay to show you which parts of your app are being color blended. Green is opaque, red is alpha:
The object of this is to minimize the amount of red (bad!) on the screen as much as possible when animations are occurring. Sometimes, not all of it can be eliminated, due to design requirements, but reducing it as much as possible will produce good results.
3) I am not sure how you are accomplishing the rounded corners on your images, but this is extremely costly to animate in a tableview if you are doing it by rounding the corners on the UIImageView's CALayer. If you are doing this in code, don't. It is much more performant to save off the images with the image already rounded. (But be cognizant, again, of the penalty incurred with alpha blending!)
Upvotes: 1