iPhone 多线程搜索

发布于 2024-09-05 18:48:55 字数 1593 浏览 8 评论 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.  }

I'm sort of new to any sort of multithreading and simply can't seem to get a simple search method working on a background thread properly. Everything seems to be in order with an NSAutoreleasePool and the UI being updated on the main thread. The app doesn't crash and does perform a search in the background but the search results yield the several of the same items several times depending on how fast I type it in. The search works properly without the multithreading (which is commented out), but is very slow because of the large amounts of data I am working with. Here's the code:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦太阳 2024-09-12 18:48:55

有几点:

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

Several things:

  • Multithreading shouldn't bring any performance gains on a single core cpu. If you think you see great speedups, probably your algorithm is fishy.
  • If you access a shared variable, be sure it is thread safe. It seems like you are writing your search results into one shared object. This will fail without synchronization.
  • That code looks as if all threads work on exactly the same dataset, so if one thread finds a match, the others will find the same and put it also in there.
  • Don't forget to synchronize the access to your "results object" as well when accessing it from the main thread.
断舍离 2024-09-12 18:48:55

您可能想研究一下 NSOperation。考虑创建 NSOperation 的子类,并将其添加为您发布的文件中实现的类的属性。

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

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

You may want to look into NSOperation. Consider making a subclass of NSOperation and adding one as a property of the class implemented in the file you posted.

then in - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {

you can set the object with a pointer to the search data and text. Then you can check if the object is currently running (I think) and if so, call 'cancel' on it and start it over again with the new search string. There may be a smarter way, but I would suspect NSOperation is a good place to start looking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文