Многопоточный поиск iPhone - PullRequest
0 голосов
/ 18 июня 2010

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

    - (void)filterContentForSearchText:(NSString*)searchText { 
isSearching = YES;
 NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];

 /*
  Update the filtered array based on the search text and scope.
  */

 //[self.filteredListContent removeAllObjects]; // First clear the filtered array.


 for (Entry *entry in appDelegate.entries)
 {
   NSComparisonResult result = [entry.gurmukhiEntry compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchText length])];
   if (result == NSOrderedSame)
   {
    [self.filteredListContent addObject:entry];
   }
 }

 [self.searchDisplayController.searchResultsTableView performSelectorOnMainThread:(@selector(reloadData)) withObject:nil waitUntilDone:NO];
 //[self.searchDisplayController.searchResultsTableView reloadData];

 [apool drain];
 isSearching = NO; }

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
     if (!isSearching) {
      [self.filteredListContent removeAllObjects]; // First clear the filtered array.
      [self performSelectorInBackground:(@selector(filterContentForSearchText:)) withObject:searchString];
     }
     //[self filterContentForSearchText:searchString];

        return NO;      // Return YES to cause the search result table view to be reloaded.  }

Ответы [ 2 ]

0 голосов
/ 18 июня 2010

Возможно, вы захотите взглянуть на NSOperation. Попробуйте создать подкласс NSOperation и добавить его в качестве свойства класса, реализованного в файле, который вы опубликовали.

затем в - (BOOL) searchDisplayController: (UISearchDisplayController *) контроллер долженReloadTableForSearchString: (NSString *) searchString {

Вы можете установить объект с указателем на данные поиска и текст. Затем вы можете проверить, запущен ли в данный момент объект (я так думаю), и если это так, вызвать «cancel» и запустить его заново с новой строкой поиска. Возможно, есть более разумный способ, но я подозреваю, что NSOperation - хорошее место, чтобы начать искать.

0 голосов
/ 18 июня 2010

Несколько вещей:

  • Многопоточность не должна приносить какой-либо прирост производительности на одноядерном процессоре. Если вы думаете, что видите большие ускорения, возможно, ваш алгоритм сомнительный.
  • Если вы обращаетесь к общей переменной, убедитесь, что она безопасна для потоков. Похоже, вы пишете результаты поиска в один общий объект. Это не удастся без синхронизации.
  • Этот код выглядит так, как будто все потоки работают с одним и тем же набором данных, поэтому, если один поток найдет совпадение, другие найдут то же самое и добавят его туда.
  • Не забудьте также синхронизировать доступ к вашему «объекту результатов» при доступе к нему из основного потока.
...