2014-07-11 6 views
1

저는 obj-c 프로그래밍에 새로운 사람입니다. 꽤 큰 데이터베이스 (8.000 이상의 항목 및 성장)를 파고 드는 iOS 앱에서 검색 창을 개발하고 있습니다.하지만 검색 필드에 입력하자 마자 입력하는 동안 필터링 결과가 반환되기 시작합니다. 많은 양의 데이터가 있으면 거의 키보드가 고정됩니다. 내 생각 엔 4 자리 숫자 뒤에 검색을 시작하게하여 8.000 이상의 항목을 찾지 않고 작은 하위 집합에서 찾았지만 코드를 사용하여 4 자리 숫자 후에 얼어 붙습니다.검색 결과를 tableview에 표시되도록 지연시키는 방법은 무엇입니까?

힌트가 있습니까?

여기

내 코드입니다, 감사 :

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    NSUInteger length = [searchText length]; 
    if (![NSString isEmpty:searchText] & (length > 3)) 
    { 
     self.filteredItems = [self.sedi filterMatch:^BOOL(id elem) 
          { 
           Sede *sede = (Sede *)elem; 
            NSArray *split = [searchText componentsSeparatedByString:@" "]; 

            return [sede.nome matchAll:split] || 
            [sede.descrizione matchAll:split] || 
            [sede.indirizzo matchAll:split] || 
            [sede.generi matchAll:split]; 
           } 
              contains:^BOOL(id elem) 
           { 
            Sede *sede = (Sede *)elem; 
            NSArray *split = [searchText componentsSeparatedByString:@" "]; 
            return [sede.nome containsAll:split] || 
            [sede.descrizione containsAll:split] || 
            [sede.indirizzo containsAll:split] || 
            [sede.generi containsAll:split]; 
           }]; 
     [self.searchDisplayController.searchResultsTableView reloadData]; 
    } 
} 
+0

당신이하고 싶은 것은 사소한 것이 아닙니다. 1) 백그라운드에서 각 검색을 수행해야합니다. 주 스레드에서 장기 실행 프로세스를 수행하지 마십시오. 2) 사용자가 검색 창에 입력 할 때 이전 검색을 취소하고 업데이트 된 검색어로 새 검색을 시작해야합니다. – rmaddy

+0

더 쉬운 해결책? 나는 또한 내가 처음에 생각한 것과는 다른 접근 방식에 열려있다. 검색을 시작하기 위해 단추 또는 키보드 단추로 검색을 이동시킬 수 있습니까? – DavideC

+0

검색을 트리거하는 방법과 상관없이 백그라운드에서 수행해야하므로 UI가 차단되지 않습니다. 사용자가 입력 한 각 문자를 처리하는 대신 사용자가 검색 버튼을 누른 후에 한 번의 검색 만 수행하면 더 쉽게 작업을 수행 할 수 있습니다. – rmaddy

답변

1

우선, rmaddy 말했듯이, 당신은 단지 사용자가 단순화하기위한 "검색"버튼을 누르면 가진 더 좋을 수 있습니다.

그렇다면 NSOperationQueue을 사용하여이를 수행 할 수 있어야합니다.

첫째, 바르 재산 작성 : 그럼 아마 어딘가에 viewDidLoad

_searchOperationQueue = [NSOperationQueue new]; 
_searchOperationQueue.maxConcurrentOperationCount = 1; 

를 초기화, 그리고

NSOperationQueue *_searchOperationQueue; 

를,이 같은 NSOperation에 코드를 포장 할 수 있어야한다 :

- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText 
{ 
    // cancel any existing search 
    [_searchOperationQueue cancelAllOperations]; 

    // begin new search 
    [_searchOperationQueue addOperationWithBlock:^{ 
     NSUInteger length = [searchText length]; 
     if (![NSString isEmpty:searchText] && (length > 3)) 
     { 

      NSArray *filteredTemp = [self.sedi filterMatch:^BOOL(id elem) 
            { 
            Sede *sede = (Sede *)elem; 
             NSArray *split = [searchText componentsSeparatedByString:@" "]; 

             return [sede.nome matchAll:split] || 
             [sede.descrizione matchAll:split] || 
             [sede.indirizzo matchAll:split] || 
             [sede.generi matchAll:split]; 
            } 
               contains:^BOOL(id elem) 
            { 
             Sede *sede = (Sede *)elem; 
             NSArray *split = [searchText componentsSeparatedByString:@" "]; 
             return [sede.nome containsAll:split] || 
             [sede.descrizione containsAll:split] || 
             [sede.indirizzo containsAll:split] || 
             [sede.generi containsAll:split]; 
            }]; 
       // update view on main thread 
       dispatch_async(dispatch_get_main_queue(), ^{ 
       self.filteredItems = filteredTemp; 
       [self.searchDisplayController.searchResultsTableView reloadData]; 
       }); 
     } 
    }]; 
} 

코드를 거의 사용했습니다. 아주 좋은 결과를 가진 큰 목록을 필터링하기 위해 이것에 tical. 모델을 유지하고 주 스레드에서 액세스하는 것만으로 동기화 할 때 조심해야합니다 (이것이 결국 내가 한 것입니다).

마지막으로주의해야 할 점은 코드에서 조건부 "AND"(&&)가 아니라 "AND"(&)를 사용한다는 것입니다. 이 특별한 경우 실제로 실제로 제대로 작동 할 수도 있지만 거의 확실한 실수 였으므로 조심하십시오.

+1

감사합니다 @ 디마, 저를 위해 완벽하게 작동했습니다. 앱이 더 이상 느려지지 않기 때문에 길이 카운터가 필요 없다는 생각을 버릴 수도 있습니다. – DavideC

관련 문제