2013-03-28 2 views
3

반복하는 경우 사과 드리지만 정직하게 연구하고 최선을 다하지 않았습니다.많은 양의 텍스트를 검색하는 iOS 앱

여러 대형 교과서를 검색 할 수있는 iPad 참조 앱을 만들고 있습니다 (총 3-4k 페이지). 사용자는 검색 할 텍스트의 조합을 선택하여 자신의 용어를 넣을 수 있습니다. 앱은 모든 텍스트에서 해당 용어를 찾아 반환합니다 (테이블보기로 색인 됨).

보기 컨트롤러에는 일련의 스위치가 있습니다.이 스위치의 값은 메소드에서 NSSet으로 읽어 와서 검색 컨트롤러로 전달됩니다. 그 부분은 작동합니다.

나는 뷰 컨트롤러가 인스턴스화과의 메소드를 호출하는 SearchController 클래스가 있습니다

-(void)performSearchWithString:(NSString *)searchString andTexts:(NSSet *)texts 
{ 
for (id book in texts) { 
    if ([book isEqual:kBook1]){ 
     NSError *error = nil; 
     NSURL *url = [[NSBundle mainBundle] URLForResource:@"neiJing" withExtension:@"txt"]; 
     NSString *text = [NSString stringWithContentsOfURL:url encoding:NSStringEncodingConversionAllowLossy error:&error]; 
     [text enumerateSubstringsInRange:NSMakeRange(0, [text length]) 
           options:NSStringEnumerationByWords 
           usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
            NSRange found = [substring rangeOfString:text]; 
            if (found.location != NSNotFound) { 
             NSLog(@"%@", substring); 
            } else { 
             NSLog(@"Not found"); 
            } 
           }]; 
    } 

내가 모든 텍스트의 모든 단어를 열거 성공했다 것을,하지만 반환 값은 너무 발견되지 I "찾을 수 없음"의 끝이없는 스트림을 얻으십시오.

필자가 알고있는 각 텍스트에 테스트 문구를 삽입했으나 나오지 않았습니다.

나는이 모든 잘못에 대해 생각하고 있습니다. 비록 내가이 작품을 만들었더라도, 성능이 떨어지는 앱은 쓸만한 앱일지도 모릅니다 ... 저는 여전히 블록 주위로 머리를 감싸려고 노력하고 있습니다. 방금 많은 양의 텍스트를 검색하고 결과를 추출하기 위해 준비된 솔루션을 찾지 못했습니다. 누구나 내가 개조 할 수있는 오픈 소스 라이브러리에 대한 힌트 나 참고 사항이 있다면, 나는 매우 감사 할 것이다.

+1

디코딩 된 URL이 포함 된 교과서는 몇 권입니까? 그게 당신이 비교하고 있기 때문이죠. – CodaFi

+0

NSLog (@ "text : % @", text); – bneely

+0

유지주기가 나타납니다. 발견 된 NSRange를 계산할 필요가 없습니다. – danh

답변

2

블록으로 전달 된 각 하위 문자열의 전체 텍스트를 검색하는 것처럼 보입니다. 이 줄은 문제가 (그리고 유지 사이클의 원인) : 코드 뭔가를 찾을 필요가

NSRange found = [substring rangeOfString:text]; 

그것을 찾을 수 있습니다

NSString *findMe = @"A string we expect to find";   
[text enumerateSubstringsInRange:NSMakeRange(0, [text length]) 
         options:NSStringEnumerationByWords 
         usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
            if ([findMe isEqualToString:substring]) { 
             NSLog(@"Found %@", substring); 
            } else { 
             NSLog(@"Not found"); 
            } 
           }]; 
+0

정말 고마워요! 저것은 맞은 궤도에 저를 얻었다. NSRange found = [부분 문자열 rangeOfString : 텍스트]; 은 Apple 코드에서 가져온 것이지만 아마도 내가 사용하고있는 것 이외의 다른 문제 일 수 있습니다 ... 유지주기에 대해 더 자세히 읽어야합니다. –

+0

그래. 그것의 요지는 (변수 '텍스트'와 같이) 블록이 그들에 언급 된 변수를 유지한다는 것입니다. 검색되는 문자열은 호출자가 전달하는 블록을 유지합니다. 그래서 텍스트는 블록을 유지하는 텍스트를 보유하는 블록을 유지하므로 서로 잠근다. – danh

+0

알았어요. 전에 "EXC_BAD ACCESS"라는 오류가 발생하여 중단 된 것으로 보입니다. 보유 루프와 관련되었을 수 있습니다. 다시 한 번 감사드립니다! –

1

나는 생각하지 않는다를 코드 블록이 무엇인지 필요. 텍스트의 각 단어를 반복하며 모든 검색 문자열을 찾고자합니다. 마지막 성공한 일치를 기반으로 새 검색 범위를 설정하는 루프가 있습니다.

-(void)performSearchWithString:(NSString *)searchString andTexts:(NSSet *)texts 
{ 
for (id book in texts) { 
    if ([book isEqual:kBook1]){ 
     NSError *error = nil; 
     NSURL *url = [[NSBundle mainBundle] URLForResource:@"neiJing" withExtension:@"txt"]; 
     NSString *text = [NSString stringWithContentsOfURL:url encoding:NSStringEncodingConversionAllowLossy error:&error]; 

     NSRange searchRange = NSMakeRange(0, [text length]); 
     NSRange match = [text rangeOfString:searchString options:0 range:searchRange]; 
     while (match.location != NSNotFound) { 

      // match is the range of the current successful match 
      NSLog(@"matching range -- %@", NSStringFromRange(match)); 

      NSUInteger locationOfNextSearchRange = NSMaxRange(match); 
      searchRange = NSMakeRange(locationOfNextSearchRange, [text length] - locationOfNextSearchRange); 
      match = [text rangeOfString:searchString options:0 range:searchRange]; 
     } 
    } 
} 
관련 문제