2

UISearchDisplayController을 사용하여 빠른 검색을 수행하는 가장 좋은 방법을 찾으려고합니다.많은 데이터가 포함 된 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 개의 고유 한 우편 번호)입니다. 내 검색 항목을 우편 번호 또는 도시 이름으로 지정합니다. 나는 하나의 큰 사전이 분명히 최고의 구조는 아님을 안다. 효율성 향상을 위해 데이터를 어떻게 정리할 수 있습니까?

도와 주셔서 감사합니다.

+0

을'[self.searchDisplayController.searchResultsTableView은 reloadData]'새로 만든 스레드 만에 UI 관련 코드는 귀하의 응용 프로그램에서 호출해야 주 스레드. 아마 이것은 당신에게 문제를 일으키는 것입니다. –

답변

2

문제는 검색 문자열이 배열의 원래 문자열 중 하나보다 긴 것입니다. 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 ]; 
      } 
    } 
} 
관련 문제