带有核心数据的慢速 UISearchDisplayController

Posted

技术标签:

【中文标题】带有核心数据的慢速 UISearchDisplayController【英文标题】:Slow UISearchDisplayController with Core Data 【发布时间】:2015-05-30 22:38:57 【问题描述】:

我有一个 TableViewController 使用 NSFetchedResultsController 显示来自 Core Data 的 40 000 行。

我使用 UISearchDisplayController 实现了实时搜索(支持 ios 7)。 它可以工作,但是搜索时在键盘上输入很慢......

如果有人能指出正确的方向并告诉我哪里可能出错,我将不胜感激。

这是我的 TableViewController 中的 UISearchResultsUpdating 部分

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    ItemSearchScope scopeKey = controller.searchBar.selectedScopeButtonIndex;
    [self searchForText:searchString scope:scopeKey];
    return YES;


- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption

    NSString *searchString = controller.searchBar.text;
    [self searchForText:searchString scope:searchOption];
    return YES;


- (void)searchForText:(NSString *)searchText scope:(ItemSearchScope)scopeOption

    if (self.managedObjectContext)

    NSString *predicateFormat = @"%K CONTAINS[cd] %@";

    NSString *searchAttribute1 = @"attribute1";
    NSString *searchAttribute2 = @"attribute2";
    NSString *searchAttribute3 = @"attribute3";

    if (scopeOption == searchScopeDebut) 
        predicateFormat = @"%K BEGINSWITH[cd] %@";
    

    if (scopeOption == searchScopeFin) 
        predicateFormat = @"%K ENDSWITH[cd] %@";
    

    NSPredicate *p1 = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute1, searchText];
    NSPredicate *p2 = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute2, searchText];
    NSPredicate *p3 = [NSPredicate predicateWithFormat:predicateFormat, searchAttribute3, searchText];

    NSPredicate *predicate = [NSCompoundPredicate orPredicateWithSubpredicates:@[p1, p2, p3]];

    [self.searchFetchRequest setPredicate:predicate];

    NSError *error = nil;
    self.filteredList = [self.managedObjectContext executeFetchRequest:self.searchFetchRequest error:&error];
    if (error)
    
        NSLog(@"searchFetchRequest failed: %@",[error localizedDescription]);
    

【问题讨论】:

您的提取请求代码可能存在问题。如果 Core Data 尝试获取数千行以匹配搜索查询,它将非常慢。确保设置了 fetch 请求的“batchSize”和/或“fetchLimit”属性以加快它的速度……但一定要确保设置了“batchSize” 我尝试在我的 fetchedResultsController 方法中添加“ [fetchRequest setFetchBatchSize:20]; ”,但它不会影响 UISearchDisplayController 的性能不佳 【参考方案1】:

我最终使用 NSTimer 来延迟 shouldReloadTableForSearchString 方法。 searchTimerPopped 选择器仅在用户停止键入键盘 2 秒时触发。

@property (nonatomic, retain) NSTimer *searchTimer;

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString

    if (self.searchTimer) 
        [self.searchTimer invalidate];
        self.searchTimer = nil;
    
    self.searchTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(searchTimerPopped:) userInfo:searchString repeats:FALSE];
    return NO;


- (void)searchTimerPopped:(NSTimer *)timer 
    NSString *searchString = [timer userInfo];
    ItemSearchScope scopeKey = self.searchDisplayController.searchBar.selectedScopeButtonIndex;
    [self searchForText:searchString scope:scopeKey];
    [self.searchDisplayController.searchResultsTableView reloadData];

【讨论】:

以上是关于带有核心数据的慢速 UISearchDisplayController的主要内容,如果未能解决你的问题,请参考以下文章

带有集合视图的 Swift 慢速自定义键盘按钮

带有 jQ​​uery 动画的慢速/无响应动画

requests.post 可以在慢速(但不是死)连接上超时吗? [复制]

在移动客户端上使用 Microsoft Sync Framework 进行慢速 SQL 同步

消息的慢速查找流程

用简单的程序实现慢速多线程