2012-04-10 3 views
0

엔티티가 Tags이고 가져 오기를 수행하여 모두 Tags이되고 NSFetchedResultsController에 할당하려고합니다. 그러나 가져온 결과의 첫 번째 객체는 Tag이고 tagName 속성은 "All"이고 그 다음 나머지는 알파벳순으로 정렬되기를 원합니다. 현재 나는 알파벳 순서로 모든 태그를 반환하지만,이 태그는 "All"이라는 이름의 태그를 항상 맨 먼저, 그 다음 나머지를 알파벳 순서로 원합니다.여러 술어가있는 요청 가져 오기?

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription 
            entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext]; 

[fetchRequest setEntity:entity]; 
NSSortDescriptor *lastDescriptor = 
[[[NSSortDescriptor alloc] initWithKey:@"tagName"ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];  

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]]; 
+0

당신이 방법 localizedCaseInsensitiveCompare을 게시 할 수 있습니다 : - (NSComparisonResult) localizedCompare가 : 선택기는 은 같은 방법으로 서명을해야합니다? 새로운 솔루션을 만들 수 있지만 가장 좋은 방법은 실제 솔루션을 최적화하는 것입니다. – ggrana

+0

그건 내 방법이 아니에요. 그냥 주어진 기본 메서드는 – Snowman

답변

2

당신은 당신에 의해 생성 된 비교가 아닌 하나 개의 기본을 사용해야합니다, 그래서 당신은 그런 일 수행 할 수 있습니다 : 예는 아래를 참조

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription 
           entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext]; 

[fetchRequest setEntity:entity]; 
NSSortDescriptor *lastDescriptor = 
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:YES comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) { 

    if ([tag1 isEqualToString:@"All"]) return NSOrderedAscending; 
    if ([tag2 isEqualToString:@"All"]) return NSOrderedDescending; 

    return [tag1 compare:tag2]; 
}] autorelease];  

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]]; 

편집

처럼을 @ 앤드류 매드슨 (Antrew Madsen)은 비교자를 사용할 수 있다고 말했지만, 나는 당신이 이미 당신의 질문에 답한 것을 보지 못했습니다.

당신은 너무 선택기를 사용할 수 있습니다

, 그냥 비교를 할 모델의 방법을 그것을 구현해야, 내가 실수를하고 당신이 사과 문서에서, 무엇을하고 있는지 믿었 무엇 :

선택자

개체의 속성을 비교할 때 사용할 방법 인 (예 : caseInsensitiveCompare : 또는 localizedCompare :). 선택기 은 keyPath로 식별되는 속성 값으로 구현 된 메서드를 지정해야합니다. 비교에 사용되는 선택기에는 단일 매개 변수, self와 비교할 개체가 전달되고 은 적절한 NSComparisonResult 상수를 반환해야합니다. (있는 NSString *) aString이

+0

tag1과 tag2가 둘 다 "모두"이면 비교기는 아마도 NSOrderedSame을 반환해야합니다. 아마도 현실에서는 문제가되지 않을 것입니다. –

+0

네 말이 맞아,하지만 이건이 특별한 경우에는 관련이 없다고 생각해. – ggrana

+0

숫자로 시작하는 tagNames가 있으면 실제로는 제대로 작동하지 않습니다. 위의 코드를 편집하여 숫자가있는 태그 위에 "모두"가 표시되게하려면 어떻게해야합니까? – Snowman

1

사용자 지정 비교 방법을 사용하여 NSSortDescriptor 자체에서이 작업을 수행 할 수 있습니다. 그러나 가져 오기 요청을 가져온 후에 가져 오기 요청의 결과를 정렬 할 수도 있습니다. NSArray는 -sortedArrayUsingComparator:이라는 메서드를 사용하여 블록을 사용하여 배열을 정렬 할 수 있으므로 사용자 정의 정렬 동작을 매우 쉽게 만들 수 있습니다.

NSArray *sortedResults = [results sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    NSString *tag1 = [obj1 tagName]; 
    NSString *tag2 = [obj2 tagName]; 

    BOOL tag1IsAll = [tag1 isEqualToString:@"All"]; 
    BOOL tag2IsAll = [tag2 isEqualToString:@"All"]; 
    if (tag1IsAll && !tag2IsAll) return NSOrderedAscending; 
    if (tag2IsAll && !tag1IsAll) return NSOrderedDescending; 

    return [tag1 compare:tag2]; 
}]; 
+0

하지만 그것은 NSFetchedResultsController에서 UITableView를 사용하고 있기 때문에 그것이 내 데이터 소스가 될 필요합니다. – Snowman

+0

정렬 설명자 선택기 옵션에 추가 한이 방법을 어떻게 든 적용 할 수 없습니까? – Snowman

+0

예, 죄송합니다. NSFetchedResultsController를 사용하고 있다는 사실을 기억하지 못했습니다. 나를 위해 아침에 너무 일찍 ;-). ggrana의 대답은 NSSortDescriptor로이 동일한 작업을 수행 할 수있는 방법을 보여줍니다. –

관련 문제