NSFetchedResultsController 加载整个数据并且性能不佳

Posted

技术标签:

【中文标题】NSFetchedResultsController 加载整个数据并且性能不佳【英文标题】:NSFetchedResultsController loads the whole data and bad performance 【发布时间】:2013-06-14 12:02:17 【问题描述】:

我有一个包含 8000 多个条目的大型数据库。我想在tableview 中加载和列出。我用NSFetchedResultsController。除了性能不佳外,它工作正常。找到教程here

并在viewDidLoad: 方法中添加了我的performFetch: 方法。但是加载视图需要 2-3 秒。

这是我的代码。

- (void)loadFetchResultsController 
    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) 
        // Update to handle the error appropriately.
        NSLog(@"Error occurs while fetching the foods with fetch results controller %@, %@", error, [error userInfo]);
        exit(-1);
    


- (NSFetchedResultsController *)fetchedResultsController

    if (isSearching)
    
        [NSFetchedResultsController deleteCacheWithName:@"SearchResults"];
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Food" inManagedObjectContext:_managedObjectContext];
    NSPredicate *hiddenPredicate = [NSPredicate predicateWithFormat:@"hidden == %@",[NSNumber numberWithBool:NO]];
    if (isSearching)
    
        hiddenPredicate = [NSPredicate predicateWithFormat:@"(hidden == %@) AND (name contains[cd] %@ OR foodDescription contains[cd] %@)",[NSNumber numberWithBool:NO], searchTerm,searchTerm];
    
    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:hiddenPredicate];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
                              initWithKey:@"name" ascending:YES];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_managedObjectContext sectionNameKeyPath:@"name.stringGroupByFirstInitial" cacheName:(isSearching) ? @"SearchResults" : @"Root"];
    _fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;

我使用了工具,发现调用 performFetch: 方法是在viewDidLoad: 调用时第一次加载整个数据。

我的food数据模型是这样的:

任何提高性能和消除延迟的想法。任何帮助将不胜感激。

【问题讨论】:

问题是仅出现在搜索谓词中还是一般情况下? 它通常发生.. 只有当搜索栏搜索发生时,该搜索谓词才有效。 @MartinR 知道为什么会这样吗?我做错什么了吗? 我知道不区分大小写的查询(例如“name contains[cd]”)可能会很慢,但这仅适用于您有搜索表达式的情况。除此之外,我目前在您的代码中没有发现问题。 隐藏和名称属性是否已在您的模型中编入索引? 【参考方案1】:

我相信您需要为您的提取请求设置提取限制,而不仅仅是批量大小。尝试调用 [fetchRequest setFetchLimit:20];看看是否有帮助。这应该会导致前 20 条记录被提取。然后当用户滚动浏览您的数据时,发出额外的 fetch 请求以获取更多数据。

【讨论】:

抓取限制是对整个抓取请求的限制。它不会像批量大小一样。如果我像你说的那样设置一个限制,我只会得到 20 个项目,当用户滚动时我什么也得不到。我也试过了。

以上是关于NSFetchedResultsController 加载整个数据并且性能不佳的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?