UISearchDisplayController и производительность поиска с большим количеством данных - PullRequest
2 голосов
/ 12 апреля 2010

Я пытаюсь найти лучший способ выполнить быстрый поиск, используя 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 уникальных почтовых индексов, поскольку несколько городов могут иметь один и тот же почтовый индекс). Я хочу, чтобы в качестве элемента поиска использовался почтовый индекс или название города. Я знаю, что один большой словарь определенно не самая лучшая структура. Как я могу организовать свои данные для большей эффективности?

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

1 Ответ

2 голосов
/ 12 января 2011

Проблема в том, что ваша строка поиска длиннее одной из ваших исходных строк в массиве. При сравнении от 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 ];
          }
     }
}
...