我的tableview的加载时间有问题,我该如何改进?加载大约90000多行的tableview大约需要25-30秒。我的sqlite数据库中有大约130000行,我使用核心数据访问该数据。
非常感谢任何帮助或建议。
感谢您的时间,如果您需要更多信息,请告诉我们。
我一直在努力优化的两件事。
+ 核心数据 - 也许我的数据提取可以改进,但我不知道我还能做什么,下面列出的代码。
if (fetchedResultsController != nil)
{
return fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:@"DataModel" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"subsection" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
//[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"section == [c] %@ AND area == 'Tables'", tablesSection]];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"area == 'Tables'"]];
[fetchRequest setFetchBatchSize:100];
//[fetchRequest setFetchLimit:100];
[fetchRequest setFetchOffset:10];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:@"uppercaseFirstLetterOfNameTables" cacheName:nil];
self.fetchedResultsController = theFetchedResultsController;
fetchedResultsController.delegate = self;
return fetchedResultsController;
+ tableview ,我认为我加载数据的方式可能是这里的主要问题。我动态计算每个单元格的高度,我认为这会减慢速度,如果我删除方法 heightForRowAtIndexPath 的代码,我可以将加载时间缩短到8秒。
(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Model *info;
if(self.searchDisplayController.isActive)
{
info = [searchFetchedResultsController objectAtIndexPath:indexPath];
}
else
{
info = [fetchedResultsController objectAtIndexPath:indexPath];
}
NSString *subsectionHeight = info.subsection;
NSString *textHeight = info.text;
CGSize titleSize = [subsectionHeight sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:20] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];
CGSize detailSize = [textHeight sizeWithFont:[UIFont fontWithName:@"Helvetica-Bold" size:16] constrainedToSize:CGSizeMake(300, MAXFLOAT) lineBreakMode:UILineBreakModeWordWrap];
return detailSize.height+titleSize.height;
//return 88;
}
(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];
cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.detailTextLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;
cell.detailTextLabel.numberOfLines = 0;
}
//if-statement need to prevent search index issue
if(self.searchDisplayController.isActive && [self.searchDisplayController.searchBar.text isEqualToString:@""])
{
return cell;
}
// Configure the cell...
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Model *info;
if (self.searchDisplayController.isActive)
{
info = [searchFetchedResultsController objectAtIndexPath:indexPath];
}
else
{
info = [fetchedResultsController objectAtIndexPath:indexPath];
}
cell.textLabel.text = info.subsection;
cell.detailTextLabel.text = info.text;
}
更新:我正在使用已注释掉heightForRowAtIndexPath的解决方案,但我需要有关搜索优化的帮助,有人可以帮助我了解如何在WWDC 2010会话中实施解决方案137优化核心数据性能,我不明白创建一个新的实体部分,例如我是否需要使用数据填充新实体?
答案 0 :(得分:1)
你必须对你的tableview进行分页:在tableview的末尾放一个显示更多结果的按钮 (我无法想象我自己在9000行上滚动)
答案 1 :(得分:0)
你绝对不需要调用heightForRowAtIndexPath 9000次,只需将IB中的高度设置为你需要的高度并取出该方法。 9000条记录的8秒实际上并没有那么糟糕。
9000记录是TableView要处理的很多记录。无论如何你可以减少这个#?
答案 2 :(得分:0)
如果你需要填充你的UITableViewCell属性是“text”和“subsection”,那么你可以将主表拆分为一个只有这两个属性的表,也许是一个关键字段,并将所有其他属性放在另一个表,一对一链接。 如果所有记录都被读入内存(当你启动UITableview时不应该正常发生),那么如果表较小(即只包含几列),则所需的时间会少得多。我在主表上移动了一个图像区域,同时在主表中留下了大约5个字段和5个关系,并且在iPad 2上的150.000条记录没有问题。
但是您应该通过记录Core Data正在使用的实际SQL语句来测试实际发生的事情(通过在启动时传递-com.apple.CoreData.SQLDebug 1作为参数)。
如果您的应用程序运行良好,则只有最初显示的记录才会触发heightForRowAtIndexPath方法。所以不是130.000倍,而是最大值。 10次显示第一个结果。所以通常不应该是你的问题。
分页也可以是一种解决方案。但在正常情况下,核心数据会在幕后自动处理分页。只需设置fetchBatchSize就足以让它自动发生。