Tableview加载缓慢

问题描述:

我遇到了我的tableview的加载时间问题,我该如何改进呢?加载约90000行以上的表格视图大约需要25-30秒。我在我的sqlite数据库中有大约130000行,我使用核心数据访问数据。Tableview加载缓慢

任何帮助或建议将不胜感激。

谢谢你的时间,如果你需要更多的信息,请让我知道。

我一直试图优化的两件事。

+ 核心数据 - 也许我提取的数据可以改进,但我不知道我能做什么,下面列出的代码。

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;  

+ 的实现代码如下,我想我在加载数据的方式可能是主要的问题在这里。我动态地计算每个单元格的高度,我认为这会减慢速度,如果我删除方法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优化核心数据的表现,我不明白创建一个新的实体部分,例如我是否需要用数据填充新的实体?

+1

对于单个表视图,90000行是荒谬的。没有人会永远能够滚动到最后。把你的数据分成不同的部分,并有一个导航结构。 – jrturton 2012-04-03 09:22:13

+0

我同意单个tableview的90000行是疯狂的,但不幸的是,这是我给的,我很想打破数据,但我不知道如何做到这一点,因为它的SAP表数据。 – JingJingTao 2012-04-03 10:00:36

必须分页的实现代码如下:把一个按钮,显示出对的tableview 结束的词(我无法想象在9000行我的自我滚动)

+0

感谢您的回复,听起来像一个好主意,但不知道如何在tableview中实现这一点,你有链接到一些示例代码? – JingJingTao 2012-04-03 10:08:14

+0

查看本教程http://www.ke-cai.net/2011/04/pagination-with-uitableview-in-ios.html – touti 2012-04-03 10:12:36

+0

酷,看看,会尝试看看我能得到什么。 – JingJingTao 2012-04-03 10:41:22

你肯定不需要调用heightForRowAtIndexPath 9000次,只需将IB中的高度设置为所需的高度并采用该方法即可。实际上9000记录的8秒并不是那么糟糕。

9000记录是一个很多的TableView来处理。无论如何你可以减少这个#?

+0

我想将数据分解成几个类别,但不幸的是我不知道如何去做,我对数据并不熟悉。 – JingJingTao 2012-04-03 10:12:52

+0

如果删除了那个heightForRow方法,那么加载时间是多少?当我说删除它时,我的意思是评论整个方法并在IB中设置单元格高度。 – 2012-04-03 11:21:36

+0

如果我注释掉heightForRow,加载需要大约8秒的时间。这就是我目前的工作。 – JingJingTao 2012-04-03 11:34:34

如果你需要填充你的UITableViewCell属性是“text”和“subsection”,那么你可以将你的主表分成一个表,只有这两个属性,也许一个关键字段,并把所有其他属性另一个表,一对一链接。 如果所有记录都读入内存中(当启动UITableview时,这些记录不应该正常发生),那么如果表格较小(即只包含少量列),它将花费更少的时间。让我感动的像场把我的主表,同时保留约5个字段,并在主表5间的关系,以及对一个iPad 2

以150.000记录没有问题,但你应该测试真正通过登录实际情况Core Data正在使用的SQL语句(通过在启动时将-com.apple.CoreData.SQLDebug 1作为参数传递)。

如果您的应用运行良好,则只有最初显示的记录应激发heightForRowAtIndexPath方法。所以不是130.000次,但最大。显示第一个结果10次。所以这通常不应该是你的问题。

分页也可能是一个解决方案。但在正常情况下,核心数据会在幕后自动处理分页。只需设置fetchBatchSize就足以让它自动发生。