使用自定义UITableViewCells(一条破损的logging)改进了ViewController的加载速度

我有一个UITableView UITableView加载非常慢(可能慢),我可以告诉它是由于在ViewController拥有的我分组的UITableView中为UITableViewCells设置自定义背景图像。

我认为我遵循这个其他SO问题中提到的build议: 提高iPhone UITableView滚动性能的技巧

我也跟着这篇文章,以确保我没有做一些愚蠢的事情: 可爱与爱定制UITableView绘图

一旦我不调用后台样式代码,性能提高。

遵循这些build议,我正在执行所有这些步骤:

  • 由于devise的方式,我有2个不同的单元格变化,不能有统一的行高度。 无论单元格的变化如何,行背景总是3个图像中的1个,并且基于行索引。 0:top_row_image,n-1:bottom_row_image,所有其他:middle_row_image
  • 我在我的ViewController的viewDidLoad中加载用于背景的图像。
  • 我没有任何drawRect代码,因为我让单元格内的UITextField处理
  • 单元格的图层设置为不透明
  • 单元标识符正在被重用
  • 不从NIB文件加载单元格

基本上,我想根据不同types的行types,使用不同的顶部,中间和底部行背景图像对表格的每一行进行样式设置。 任何人都可以提出一个更好的方法来在UITableView上有自定义的背景吗?

这是我的代码:

ViewController: @property (nonatomic, weak) IBOutlet *tableview; @property (nonatomic, strong, readwrite) UIImage *topRowImage; @property (nonatomic, strong, readwrite) UIImage *middleRowImage; @property (nonatomic, strong, readwrite) UIImage *bottomRowImage; @synthesize tableview = _tableview; @synthesize topRowImage = _topRowImage; @synthesize middleRowImage = _middleRowImage; @synthesize bottomRowImage = _bottomRowImage; // Load the images that will be used for the cell background ahead of time - (void)viewDidLoad { [super viewDidLoad]; // All of the images are 60x20 but my cells are 300x44 or 300x56 UIEdgeInsets edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4); self.topRowImage = [[UIImage imageNamed:@"top_row.png"] resizableImageWithCapInsets:edgeInsets]; UIEdgeInsets edgeInsets = UIEdgeInsetsMake(0, 4, 0, 4); self.middleRowImage = [[UIImage imageNamed:@"middle_row.png"] resizableImageWithCapInsets:edgeInsets]; edgeInsets = UIEdgeInsetsMake(2, 4, 2, 4); self.bottomRowImage = [[UIImage imageNamed:@"bottom_row.png"] resizableImageWithCapInsets:edgeInsets]; } - (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *cellId = [self getCellIdAt:indexPath]; BaseCustomTableViewCell *cell = (BaseCustomTableViewCell *)[aTableView dequeueReusableCellWithIdentifier:cellId]; if (cell == nil) { if ([cellId isEqualToString:@"CellId1"]) { cell = [[CustomTableViewCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } else { cell = [[CustomTableViewCell2 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId]; } } // the following line seems to be the bottleneck [self styleBackground:cell indexPath:indexPath totalRows:totalRows]; [cell configureData:myRowData]; } - (void)styleCellBackground:(BaseCustomTableViewCell *)cell indexPath:(NSIndexPath *)indexPath totalRows:(NSInteger)totalRows { UIImage *backgroundImage = nil; if (indexPath.row == 0) { // Top row of this section backgroundImage = self.topRowImage; // ivar loaded during 'viewDidLoad' } else if (indexPath.row == totalRows - 1) { // Bottom row of this section backgroundImage = self.bottomRowImage; } else { // Middle row of this section backgroundImage = self.middleRowImage; } [cell updateRowBackground:backgroundImage]; } @implementation CustomTableViewCell -(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { // Create my text field _textField = [[UITextField alloc] initWithFrame:CGRectZero]; _textField.backgroundColor = [UIColor whiteColor]; self.backgroundColor = [UIColor whiteColor]; self.contentView.backgroundColor = [UIColor whiteColor]; self.backgroundView = [[UIImageView alloc] init]; // not sure which of these should be set to opaque to ensure to meet criteria #4 // 4. Make your UITableViewCell's layer opaque (same goes for the content view if you have one) self.backgroundView.opaque = YES; self.layer.opaque = YES; self.opaque = YES; self.contentView.opaque = YES; [self.contentView addSubview:_textField]; } } - (void)layoutSubviews { CGRect textFieldFrame = CGRectMake(10, 2, 278, 40); self.textField.frame = textFieldFrame; [super layoutSubviews]; } - (void)updateRowBackground:(UIImage *)rowBackground { ((UIImageView *)self.backgroundView).image = rowBackground; } 

我认为如果停止在每次调用cellForRowAtIndexPath切换每个单元格的背景图像,您会看到显着的性能提升。

这听起来像你有三种单元格(“顶”,“中”和“底”)。 您可以停止重复使用它们,因此必须在每次使用时重置背景图像。

相反,您可以使用不同的标识符来初始化表格单元格的实例,具体取决于表格中的位置。 这样你就可以创build一个带有“顶部”标识符的单元,带有“底部”标识符的单元以及带有“中”标识的许多单元。 然后,您只能在初始化单元格时设置其背景图像。 只要您尝试重复使用具有适当标识符的单元格,就不再需要每次都更改其背景图像。