2

我有这个问题,我一直在推迟解决,但现在是时候了。

我有一个基本的字典程序。它有一个 UISearchBar 和一个 UITableView。它以应有的方式工作,除非在设备上运行时会导致键盘滞后。(模拟器当然可以)我有两种搜索方式。即用型和返回型。我发现两者都需要大约相同的时间来返回结果,但是 As-you-type 会使键盘滞后。

我有 UISearchBar textDidChange 接受 searchText 并将其发送到执行所有 sqlite 提升的搜索方法,将结果放入数组中。重新加载表。

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
    if((searchType == SEARCH_AS_YOU_TYPE) && ([searchText length] >= 2)){
        NSString *myKeyword = [NSString stringWithFormat:@"%@", searchText];
        [self search:myKeyword];
        [myTableView reloadData];
    }
}

我将结果限制为 50。我的 SQL 查询使用 LIKE 和 OR,但目前还没有办法。

SELECT WORD_ID, DEFIN, PINYIN, SIMP, TRAD from WORDS where DEFIN LIKE "%to dog %" OR DEFIN LIKE "%dog" OR DEFIN LIKE "%dog%"  ORDER BY DEFIN LIMIT 50

我还尝试将 [myTableView reloadData] 移动到搜索方法中,希望键盘至少不会滞后。没有喜悦。可悲的是,我知道当 sqlite 使用 like 运算符时,它基本上会检查每一行。但是 80 行的 3-4 秒似乎有点慢。

任何想法、想法、意见或建议将不胜感激!

4

5 回答 5

8

在我看来,您正在同一线程中搜索并准备好键盘。这样,您将搜索尽可能多的字符,并且输入速度仅限于搜索速度。

一个适当的解决方案是将其分成两个线程,一个用于读取和显示键盘,第二个用于搜索并显示搜索结果。这样,如果您的输入速度比搜索速度快,则只有搜索会滞后,而输入不会滞后。例如,Firefox 地址栏就是这样工作的。

由于两个线程以及两者之间的通信/协调,您的代码将更加复杂,但我认为这是唯一好的解决方案。

于 2009-05-04T11:05:15.993 回答
3

以下是我猜测 SQLite 执行该查询的方式:

  1. 查找与您的 LIKE 语句之一匹配的所有行。

  2. 按 DEFIN 对它们进行排序。

  3. 在前 50 行之后截断结果。

我怀疑真正痛苦的部分是那种。没有它,它可以简单地收集它找到的前 50 个匹配行。你能不对定义进行排序吗?

于 2009-05-04T10:58:18.413 回答
1

因为您使用的是 LIKE sqlite 不会使用索引,它会从头开始顺序扫描,直到结果集中达到 50 条记录的限制。根据您数据的顺序,它可能会在最坏的情况下在开始或结束时达到前 50 个结果。

您如何创建一个新列,将每个基本单词的第一个字母存储在定义中,例如 dog 等,并索引该列。

修改您的查询以选择 * from words where fisrtletter = :firstletter order by defin limit 50

这将大大减少您的搜索空间

使用 like 运算符进行完全匹配

您也可以预先订购数据,这样就不需要 order by,我怀疑 order by 将导致扫描整个表,而不是在前 50 条记录被命中时终止

于 2009-05-06T05:31:52.223 回答
0

尝试在不同的线程中进行搜索查询。由于 UI 操作仅在主线程上执行,因此在主线程上进行的任何耗时操作都会延迟 UI 操作。

于 2009-05-04T12:17:19.330 回答
0

我一般用

[self performSelectorInBackground:@selector(threadedFetch) withObject:nil];

结合 Core Data'sNSFetchedResultsController在用户搜索输入时开始获取。但是踩的时候要小心。对每个线程使用单独NSManagedObjectContext的或使用您锁定的单个上下文-[NSManagedObjectContext lock]

于 2010-05-04T17:50:03.843 回答