1

У меня есть TableViewController, отображающий как 40 000 строк из Core Data с NSFetchedResultsController.Slow UISearchDisplayController с базовыми данными

Я реализовал прямой поиск с помощью UISearchDisplayController (поддержка IOS 7). Он работает, но набирает клавиатуру при поиске очень медленно ...

Я бы очень признателен, если бы кто-то мог указать мне в правильном направлении и показать, где я могу ошибиться.

Вот UISearchResultsUpdating часть в моем TableViewController

- (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]); 
    } 
} 

}

+0

Проблема, вероятно, существует с кодом запроса на выборку. Core Data будет очень медленным, если он пытается получить тысячи строк в соответствии с поисковым запросом. Убедитесь, что вы задали свойства «batchSize» и/или «fetchLimit» запроса на выборку, чтобы ускорить его .... Определенно убедитесь, что вы устанавливаете «пакетный размер», хотя – DBoyer

+0

Я попытался добавить «[fetchRequest setFetchBatchSize: 20]; «в моем методе fetchedResultsController, но это не влияет на низкую производительность UISearchDisplayController – Rui

ответ

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]; 
} 
Смежные вопросы