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 の一意の郵便番号)。検索項目を郵便番号または都市名にしたい。1 つの大きな辞書が最適な構造ではないことはわかっています。より効率的にデータを整理するにはどうすればよいですか?

これを手伝ってくれてありがとう。

4

1 に答える 1

2

問題は、検索文字列が配列内の元の文字列の1つよりも長いことです。0から[検索長]までを比較すると、sの範囲外になっています。まず、sが検索よりも長いことを確認する必要があります。

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 に答える