简体   繁体   English

如何延迟搜索结果显示在表格视图中?

[英]How to delay search results to appear in tableview?

I'm a new on programming, especially obj-c. 我是编程方面的新手,尤其是obj-c。 I'm developing a search bar in an iOS app that dig into a quite big database (8.000+ entries and growing), but as soon as I type in the search field, it starts to give back results filtering while typing because of the large amount of data, it almost freeze the keyboard. 我正在iOS应用程序中开发一个搜索栏,该搜索栏可以挖掘到一个很大的数据库(8.000个以上的条目并在不断增长),但是一旦我在搜索字段中键入内容,由于输入的内容很大,它会开始过滤返回结果大量的数据,它几乎冻结了键盘。 My guess was to let the search start after 4 digits, so instead of looking out from 8.000+ entries it would have do it out of a smaller subset, but with the code I wrote it keeps on freezing, after 4 digits... 我的猜测是让搜索开始于4位数字,因此与其从8.000+个条目中查找,不如从较小的子集中进行搜索,但是用我编写的代码,它在4位数字之后一直冻结。

Any hints? 有什么提示吗?

Thank you, 谢谢,

Here is my code: 这是我的代码:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    NSUInteger length = [searchText length];
    if (![NSString isEmpty:searchText] & (length > 3))
    {
        self.filteredItems = [self.sedi filterMatch:^BOOL(id elem)
                          {
                              Sede *sede = (Sede *)elem;
                                  NSArray *split = [searchText componentsSeparatedByString:@" "];

                                  return [sede.nome matchAll:split] ||
                                  [sede.descrizione matchAll:split] ||
                                  [sede.indirizzo matchAll:split] ||
                                  [sede.generi matchAll:split];
                              }
                                           contains:^BOOL(id elem)
                              {
                                  Sede *sede = (Sede *)elem;
                                  NSArray *split = [searchText componentsSeparatedByString:@" "];
                                  return [sede.nome containsAll:split] ||
                                  [sede.descrizione containsAll:split] ||
                                  [sede.indirizzo containsAll:split] ||
                                  [sede.generi containsAll:split];
                              }];
        [self.searchDisplayController.searchResultsTableView reloadData];
    }
}

First off, as rmaddy said, you may be better off just having the user hit the "Search" button for simplicity's sake. 首先,正如rmaddy所说,为简单起见,让用户点击“搜索”按钮可能会更好。

That said, you should be able to accomplish this with an NSOperationQueue . 也就是说,您应该可以使用NSOperationQueue来完成此NSOperationQueue

First, create an ivar or property: 首先,创建一个ivar或属性:

NSOperationQueue *_searchOperationQueue;

Then, initialize it somewhere, probably viewDidLoad 然后,在某处初始化它,可能是viewDidLoad

_searchOperationQueue = [NSOperationQueue new];
_searchOperationQueue.maxConcurrentOperationCount = 1;

Then, you should be able to wrap your code in an NSOperation like this: 然后,您应该能够将代码包装在NSOperation如下所示:

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
    // cancel any existing search
    [_searchOperationQueue cancelAllOperations];

    // begin new search
    [_searchOperationQueue addOperationWithBlock:^{
        NSUInteger length = [searchText length];
        if (![NSString isEmpty:searchText] && (length > 3))
        {

          NSArray *filteredTemp = [self.sedi filterMatch:^BOOL(id elem)
                                  {
                                  Sede *sede = (Sede *)elem;
                                      NSArray *split = [searchText componentsSeparatedByString:@" "];

                                      return [sede.nome matchAll:split] ||
                                      [sede.descrizione matchAll:split] ||
                                      [sede.indirizzo matchAll:split] ||
                                      [sede.generi matchAll:split];
                                  }
                                               contains:^BOOL(id elem)
                                  {
                                      Sede *sede = (Sede *)elem;
                                      NSArray *split = [searchText componentsSeparatedByString:@" "];
                                      return [sede.nome containsAll:split] ||
                                      [sede.descrizione containsAll:split] ||
                                      [sede.indirizzo containsAll:split] ||
                                      [sede.generi containsAll:split];
                                  }];
              // update view on main thread
              dispatch_async(dispatch_get_main_queue(), ^{
                self.filteredItems = filteredTemp;
                [self.searchDisplayController.searchResultsTableView reloadData];
              });
        }
    }];
}

I have used code almost identical to this for filtering large lists with very good results. 我使用几乎与此相同的代码来过滤大型列表,并获得了很好的结果。 You just have to be careful to keep the model and view in sync by only accessing it on the main thread (which is what I did at the end). 您只需要注意仅在主线程上访问模型即可保持模型和视图同步(这是我最后做的)。

One last thing to note is that you were using a bitwise "AND" ( & ) rather than a conditional "AND" ( && ) in your code, which I corrected in my answer. 最后要注意的一点是,您在代码中使用的是按位“ AND”( & ),而不是有条件的“ AND”( && ),我在回答中对此进行了更正。 While it may actually function correctly in this particular case, it was almost certainly a mistake, so be careful. 尽管在此特定情况下它实际上可以正确运行,但几乎可以肯定是一个错误,因此请小心。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM