NSPredicate
을 사용하여 NSManagedObject
인스턴스의 배열을 검색하고 있습니다. 각 "기사"는 "제목", "내용"을 가지며 잠재적으로 여러 "태그"와 일치합니다.이 NSPredicate를 최적화 하시겠습니까?
기사의 내용과 일치시키는 정규식을 사용하고 싶습니다. 다른 검색 연산자는 다른 모든 항목에 적합합니다. 문제는 내 검색이 아주 천천히 진행된다는 것입니다. 다음은 내가 가지고있는 것입니다.
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
//
// Grab a local copy of the search string.
// This is done simply for convenience in the
// following set of if statements.
//
NSMutableString *modifiedSearchString = [searchString mutableCopy];
NSPredicate *predicate;
//1 is "content" and 3 is "all"
if(scopeIndex == 1 || scopeIndex == 3){
NSInteger length = [searchString length];
NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?";
//If our search includes the body of the text
for (int i = length; i > 0; i--) {
[modifiedSearchString insertString:vowelsAsRegex atIndex:i];
}
[modifiedSearchString insertString:@".*" atIndex:0];
[modifiedSearchString appendString:@".*"];
}
//
// Depending on the selected scope bar option
// we perform a "MATCHES" search.
//
// For searching properties of related entities, we use the ANY keyword
//
//NSLog(@"Regex: %@", modifiedSearchString);
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", modifiedSearchString];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText MATCHES[cd] %@", modifiedSearchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[cd] %@) OR (articleTitle CONTAINS[cd] %@) OR (articleContent MATCHES[cd] %@)", modifiedSearchString, modifiedSearchString, modifiedSearchString];
}
[modifiedSearchString release];
NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];
//
// Ensure that we have an array to work with.
//
if (self.filteredArray == nil) {
self.filteredArray = [[[NSMutableArray alloc ] init] autorelease];
}
//
// Clear out any existing objects from earlier.
//
[filteredArray removeAllObjects];
//
// Perform the filtering by looping
// through the articles and checking
// it against the predicate.
//
for (Article *article in unfilteredResults) {
if ([predicate evaluateWithObject:article])
[self.filteredArray addObject:article];
}
//
// Release the unfiltered array.
//
[unfilteredResults release];
}
검색 속도를 높이기 위해 어떤 최적화를 적용 할 수 있습니까?
편집 : 별도의 배열을 주석을 제거, 조금 내 코드를 제거했습니다
. 나는 특별히 NSPredicate를 "contains"와 "match"를 최적화하는 방법에 대해 묻습니다. 여기에 새로운 코드가있다 :
- (void) filterArrayWithSearchTerm:(NSString *)searchString andScopeIndex:(NSInteger)scopeIndex{
NSMutableString *modifiedSearchString = [searchString mutableCopy];
NSPredicate *predicate;
if(scopeIndex == 1 || scopeIndex == 3){
NSInteger length = [searchString length];
NSString *vowelsAsRegex = @"[\u0591-\u05c4]?[\u0591-\u05c4]?"; //Trop: \u0591-\u05AF Nekudot: \u05b0-\u05c
for (int i = length; i > 0; i--) {
[modifiedSearchString insertString:vowelsAsRegex atIndex:i];
}
[modifiedSearchString insertString:@".*" atIndex:0];
[modifiedSearchString appendString:@".*"];
}
if (scopeIndex == 0) {
predicate = [NSPredicate predicateWithFormat:@"articleTitle CONTAINS[cd] %@", modifiedSearchString];
}else if (scopeIndex == 1) {
predicate = [NSPredicate predicateWithFormat:@"articleContent CONTAINS[cd] %@", modifiedSearchString];
}else if (scopeIndex == 2){
predicate = [NSPredicate predicateWithFormat:@"ANY tags.tagText MATCHES[cd] %@", modifiedSearchString];
}else{
predicate = [NSPredicate predicateWithFormat:@"(ANY tags.tagText CONTAINS[c] %@) OR (articleTitle CONTAINS[c] %@) OR (articleContent MATCHES[cd] %@)", modifiedSearchString, modifiedSearchString, modifiedSearchString];
}
[modifiedSearchString release];
NSMutableArray *unfilteredResults = [[[[self.fetchedResultsController sections] objectAtIndex:0] objects] mutableCopy];
[unfilteredResults filterUsingPredicate:predicate];
self.filteredArray = unfilteredResults;
[unfilteredResults release];
}
이 방법이 가장 좋은 해결책 일 수 있지만, 정규식을 넘어선 추가 최적화가 필요합니다. – Moshe