开发者

UISearchDisplayController and search performance with lots of data

I'm trying to figure out the best way to perform a fast search using a UISearchDisplayController.

I have a plist file with more than 36000 entries. I load this file in a dictionary and I perform the search in this dictionary. It works but it's kinda slow and there is lag between each touch event. I want an autocompletion effect so I need the search to be triggered for each touch event.

I tried using thread to perform the search in background with the following code :

- (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];
    }

But my applicat开发者_如何学JAVAion crashes randomly with the following message:

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

I'm sure it's because I dont use threading properly.

I also tried using [self performSelector:@selector(filter:) withObject:searchString afterDelay:0.5]; but I'm also facing application crashes.

What is the best way to handle this ? I'm not really good with threads but I think it's the best way to go, isn't it ? I also tried a solution with SQLite but the application is still not so responsive.

My data are actually zip codes and cities (36000 unique different cities but 6500 unique zip codes since multiple cities can have the same zip code). I want my search item to be either a zip code or a city name. I know that one big dictionary is definitely not the best structure. How could I organize my data for more efficiency?

Thank you for helping me with this.


The problem is that your search string is longer than one of your original strings in the array. When comparing from 0 to [search length] you are falling outside of s. You should first make sure that s is longer than 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 ];
          }
     }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜