2

J'essaie de trouver la meilleure façon d'effectuer une recherche rapide en utilisant un UISearchDisplayController.UISearchDisplayController et de rechercher des performances avec beaucoup de données

J'ai un fichier plist avec plus de 36000 entrées. Je charge ce fichier dans un dictionnaire et j'effectue la recherche dans ce dictionnaire. Cela fonctionne mais c'est un peu lent et il y a du décalage entre chaque événement tactile. Je veux un effet d'auto-complétion donc j'ai besoin que la recherche soit déclenchée pour chaque événement tactile.

J'ai essayé avec du fil pour effectuer la recherche en arrière-plan avec le code suivant:

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

Mais mon application se bloque au hasard avec le message suivant:

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

Je suis sûr que c'est parce que je N'utilisez pas le filetage correctement.

J'ai également essayé d'utiliser [self performSelector:@selector(filter:) withObject:searchString afterDelay:0.5]; mais je suis également confronté à des plantages d'applications.

Quelle est la meilleure façon de gérer cela? Je ne suis pas très doué avec les threads mais je pense que c'est la meilleure façon d'y aller, n'est-ce pas? J'ai également essayé une solution avec SQLite mais l'application n'est toujours pas aussi réactive.

Mes données sont en réalité des codes postaux et des villes (36000 villes différentes mais 6500 codes postaux uniques puisque plusieurs villes peuvent avoir le même code postal). Je souhaite que mon élément de recherche soit un code postal ou un nom de ville. Je sais qu'un grand dictionnaire n'est certainement pas la meilleure structure. Comment pourrais-je organiser mes données pour plus d'efficacité?

Merci de votre aide.

+0

Vous appelez '[self.searchDisplayController.searchResultsTableView reloadData]' sur votre fil nouvellement créé, mais le code lié interface utilisateur ne doit être appelée à partir de votre application fil principal. Peut-être que cela vous cause des problèmes. –

Répondre

2

Le problème est que votre chaîne de recherche est plus longue que l'une de vos chaînes d'origine dans le tableau. Lorsque vous comparez 0 à [longueur de recherche], vous tombez en dehors de s. Vous devez d'abord vous assurer que l'art est plus longue que la recherche:

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 ]; 
      } 
    } 
} 
Questions connexes