我是编程新手,特别是obj-c。 我正在iOS应用程序中开发一个搜索栏,它可以挖掘到一个非常大的数据库(8.000多个条目并且正在增长),但是一旦我输入搜索字段,它就会在打字时开始返回结果,因为它很大数据量,它几乎冻结了键盘。 我的猜测是让搜索在4位数之后开始,所以不是从8000多个条目中查找,而是从较小的子集中查找它,但是我写的代码在4位数后继续冻结...... / p>
任何提示?
谢谢,
这是我的代码:
- (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];
}
}
答案 0 :(得分:1)
首先,正如rmaddy所说,为了简单起见,让用户点击“搜索”按钮可能会更好。
那就是说,你应该能够用NSOperationQueue
完成这个。
首先,创建一个ivar或属性:
NSOperationQueue *_searchOperationQueue;
然后,在某处初始化它,可能是viewDidLoad
_searchOperationQueue = [NSOperationQueue new];
_searchOperationQueue.maxConcurrentOperationCount = 1;
然后,您应该能够将代码包装在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];
});
}
}];
}
我使用了几乎与此相同的代码来过滤大型列表并获得非常好的结果。您只需要小心保持模型和视图同步,只需在主线程上访问它(这就是我最后所做的)。
最后要注意的是,您在代码中使用了按位“AND”(&
)而不是条件“AND”(&&
),我在答案中对此进行了更正。虽然它在这种特殊情况下实际上可能正常运行,但几乎肯定是一个错误,所以要小心。