0

我对任何类型的多线程都是新手,似乎根本无法获得一个简单的搜索方法在后台线程上正常工作。NSAutoreleasePool 和主线程上更新的 UI 似乎一切正常。该应用程序不会崩溃并且会在后台执行搜索,但搜索结果会根据我输入的速度多次产生几个相同的项目。搜索在没有多线程(已被注释掉)的情况下正常工作,但由于我正在处理大量数据,所以速度非常慢。这是代码:

    - (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.  }
4

2 回答 2

0

几件事:

  • 多线程不应在单核 CPU 上带来任何性能提升。如果你认为你看到了很大的加速,可能你的算法有问题。
  • 如果您访问共享变量,请确保它是线程安全的。似乎您正在将搜索结果写入一个共享对象。如果没有同步,这将失败。
  • 该代码看起来好像所有线程都在完全相同的数据集上工作,因此如果一个线程找到匹配项,其他线程将找到相同的并将其放入其中。
  • 当从主线程访问它时,不要忘记同步对“结果对象”的访问。
于 2010-06-17T23:01:33.140 回答
0

您可能想查看 NSOperation。考虑创建一个 NSOperation 的子类,并添加一个作为您发布的文件中实现的类的属性。

然后在 - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {

您可以使用指向搜索数据和文本的指针来设置对象。然后您可以检查对象当前是否正在运行(我认为),如果是,请在其上调用“取消”并使用新的搜索字符串重新开始。可能有更聪明的方法,但我怀疑 NSOperation 是一个开始寻找的好地方。

于 2010-06-17T23:05:51.867 回答