Tableview加载速度慢

时间:2012-04-03 09:10:41

标签: ios uitableview core-data

我的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优化核心数据性能,我不明白创建一个新的实体部分,例如我是否需要使用数据填充新实体?

3 个答案:

答案 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就足以让它自动发生。

相关问题