2

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

У меня есть файл plist с более чем 36000 записей. Я загружаю этот файл в словарь, и я выполняю поиск в этом словаре. Он работает, но он медленный, и есть лаг между каждым событием касания. Я хочу эффект автозаполнения, поэтому мне нужно, чтобы поиск запускался для каждого события касания.

Я попытался с помощью нити для выполнения поиска в фоновом режиме с помощью следующего кода:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { 
       [NSThread detachNewThreadSelector:@selector(filter:) toTarget:self withObject:searchString]; 
      return NO; 
     } 

// Filter function looks like this 
-(void) filter:(NSString *)search { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     [self.filteredList removeAllObjects]; // empty array of results 
     for (NSString *s in self.keys) { 
       NSComparisonResult result = [s compare:search options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [search length])]; 
       if (result == NSOrderedSame) { 
        [self. filteredList addObject:s ]; 
       } 
     } 
     [ self.searchDisplayController.searchResultsTableView reloadData]; 
     [pool release]; 
    } 

Но мой сбой приложения случайного образом со следующим сообщением:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (0). 

Я уверен, что это потому, что я Не используйте резьбу правильно.

Я также пробовал использовать [self performSelector:@selector(filter:) withObject:searchString afterDelay:0.5];, но я также сталкиваюсь с сбоями приложений.

Каков наилучший способ справиться с этим? Я не очень хорош в потоках, но я думаю, что это лучший способ пойти, не так ли? Я также попробовал решение с SQLite, но приложение все еще не так отзывчиво.

Мои данные - это, по сути, почтовые индексы и города (36000 уникальных городов, но 6500 уникальных почтовых индексов, поскольку несколько городов могут иметь один и тот же почтовый индекс). Я хочу, чтобы мой элемент поиска был либо почтовым индексом, либо именем города. Я знаю, что один большой словарь определенно не лучшая структура. Как я могу организовать свои данные для большей эффективности?

Спасибо, что помогли мне в этом.

+0

Вы призывающую '[self.searchDisplayController.searchResultsTableView reloadData]' на вновь созданный нить, но UI-код, связанный должен вызываться только из вашего приложения основной поток. Возможно, это вызывает проблемы. –

ответ

2

Проблема в том, что ваша строка поиска длиннее одной из исходных строк в массиве. При сравнении от 0 до [длины поиска] вы падаете за пределы s. Вы должны сначала убедиться, что S больше, чем поиск:

for (NSString *s in self.keys) { 
    if ([s length]>=[search length]) { 
      NSComparisonResult result = [s compare:search options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [search length])]; 
      if (result == NSOrderedSame) { 
       [self. filteredList addObject:s ]; 
      } 
    } 
}