2

我正在尝试找出使用UISearchDisplayController.

我有一个包含 36000 多个条目的 plist 文件。我将此文件加载到字典中,然后在此字典中执行搜索。它可以工作,但有点慢,每个触摸事件之间都有延迟。我想要一个自动完成效果,所以我需要为每个触摸事件触发搜索。

我尝试使用线程在后台执行搜索,代码如下:

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
                 [NSThread detachNewThreadSelector:@selector(filter:)  toTarget:self  withObject:searchString];
           return NO;
        }

// Filter function looks like this
-(void) filter:(NSString *)search {
         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
         [self.filteredList removeAllObjects]; // empty array of results
         for (NSString *s in self.keys ) {
              NSComparisonResult result = [s compare:search options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [search length])];
              if (result == NSOrderedSame) {
                   [self. filteredList addObject:s ];
              }
         }
         [ self.searchDisplayController.searchResultsTableView reloadData];
         [pool release];
    }

但是我的应用程序随机崩溃并显示以下消息:

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (1) beyond bounds (0). 

我确定这是因为我没有正确使用线程。

我也尝试过使用[self performSelector:@selector(filter:) withObject:searchString afterDelay:0.5];,但我也面临应用程序崩溃。

处理此问题的最佳方法是什么?我不太擅长线程,但我认为这是最好的方法,不是吗?我还尝试了使用 SQLite 的解决方案,但应用程序仍然没有那么灵敏。

我的数据实际上是邮政编码和城市(36000 个不同的城市,但有 6500 个不同的邮政编码,因为多个城市可以有相同的邮政编码)。我希望我的搜索项是邮政编码或城市名称。我知道一本大字典绝对不是最好的结构。如何组织数据以提高效率?

谢谢你帮我解决这个问题。

4

1 回答 1

2

问题是您的搜索字符串比数组中的原始字符串之一长。从 0 到 [搜索长度] 进行比较时,您超出了 s。您应该首先确保 s 比 search 长:

for (NSString *s in self.keys ) {
    if ([s length]>=[search length]) {
          NSComparisonResult result = [s compare:search options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [search length])];
          if (result == NSOrderedSame) {
               [self. filteredList addObject:s ];
          }
     }
}
于 2011-01-12T08:00:25.493 回答