8

현재 NSFetchedResultsController를 사용하여 코어 데이터에서 프로젝트의 UITableView를 채우려고합니다. 나는이 탭을 입력하면, 내가 프로그램을 통해 모든 로그인 한NSFetchedResultsController 사용자 지정 정렬이 호출되지 않습니다.

if (fetchedResultsController != nil) { 
     return fetchedResultsController; 
    } 

    /* 
    Set up the fetched results controller. 
    */ 
    // Create the fetch request for the entity. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES comparator:^(id s1, id s2) { 
      NSLog(@"Comparator"); 
     //custom compare here with print statement 
    }]; 
    NSLog(@"Sort Descriptor Set"); 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstLetterOfObject" cacheName:@"Objects"]; 
    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 
    if (![fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return fetchedResultsController; 

과 NSFetchedResultsController이하는 것을 발견 : (나는 또한 셀렉터를 시도하고 동일한 문제가 있었더라도) 나는 비교기와 사용자 정의 검색을 사용하고 있습니다 페칭 할 때 비교기 블록에 들어 가지 않습니다. 대신 기본 정렬 방법으로 정렬합니다.

그러나 objectName을 사용하여 Object를 삭제하고 추가하면 비교기 블록에 들어가서 테이블을 올바르게 정렬합니다.

왜 NSFetchedResultsController는 관리 객체 모델이 변경 될 때까지 비교자를 사용하여 정렬하지 않습니까?

Notes : 캐싱을 끄거나 viewDidLoad에서 가져 오기를 시도해 보았습니다. 그러나 가져온 횟수는 중요하지 않지만 언제 사용되었는지는 알 수 없습니다. 어떤 이유로 객체 모델이 변경된 후에 만 ​​내 정렬을 사용합니다.

답변

8

은 몇 가지가 있습니다를 나는 생각할 수있다. 첫째, 이것이 문제는 아니지만 일시적인 속성을 정렬 할 수는 없습니다. 그러나 SQL 스토어를 기반으로하는 모델에서 정렬 할 때 비교기가 SQL 쿼리로 "컴파일"되고 모든 Objective-C 함수를 사용할 수있는 것은 아닙니다. 이 경우 가져 오기가 수행 된 후 메모리에서 정렬해야합니다.

편집 :이 doc을 참조하십시오. 특히 술어 가져 오기 및 설명자 정렬 섹션을 참조하십시오.

+1

일시적인 속성은 아니지만 다른 제안은 문제가 될 수있는 것처럼 보입니다. 유일한 문제는 내가 fetchedresultscontroller에 섹션 이름과 테이블 뷰를 제공하기 위해 의존하고 있으므로 매번 메모리를 정렬하는 것이 어려울 것이라고 생각합니다. 그것에 대해 어떻게 생각 하시겠습니까? 그리고 내 다른 질문은 왜 개체 모델이 변경된 후 비교 블록이 작동합니까? 고맙습니다! –

+0

사실 더 일반적인 문제는 섹션 색인과 함께 섹션을 내 테이블 뷰에 구현한다는 것입니다. 나는 "123"섹션 (이 작품)에 숫자로 시작하는 모든 오브젝트를 넣었지만,이 섹션이 iPod 앱과 같이 하단에 있도록하고 싶습니다. 애플의 애플 리케이션에 따르면, 숫자는 sectionIndex의 마지막 옵션이어야한다. (나는 섹션 인덱스를 생성하기 위해 UILocalizedIndexedCollation을 사용하고있다.) 그러나 섹션을 가져 와서 숫자가 마지막으로 오게하는 방법은 없습니다. 맞춤 정렬보다 더 신뢰할 수있는 방법을 알고 계십니까? –

+2

그냥 추측하지만 그래프가 이미 메모리에 있기 때문에 개체 모델이 변경된 후에 비교기 블록이 작동한다고 생각합니다. 그러나 그것은 단지 추측입니다. 수동으로 정렬하는 방법은 NSArrayController를 서브 클래스 화하는 것이므로 NSFetchedResultsController 이점을 잃을 것입니다. 그러나 말했듯이 근본적인 문제는 숫자를 맨 아래로 정렬하려고한다는 것입니다.내 머리 꼭대기에서, 나는 당신의 객체들에 정렬 순서 속성을 만들고 그것을 사용한다고 말하고 싶지만, 정렬 기술자를 사용하여 충분한 사용자 정의 정렬을하지 못했습니다. – Don

0

미안하지만, 당신이 마지막이 코드?에 일부를 가져 그리워 않았다

NSError *error; 
BOOL success = [aFetchedResultsController performFetch:&error]; 

도 요청 해제하는 것을 잊지 마십시오

[fetchRequest release]; 
+0

아니오, 방금 스 니펫에 포함하지 않았습니다. 그게 더 명확한 경우 전체 방법을 포함 시켰습니다. –

1

나는이 문제를 해결하기 위해 객체를 수정하고 변경 사항을 저장 한 다음 원래 값으로 복원 한 다음 다시 저장하는 방법을 사용합니다.

// try to force an update for correct initial sorting bug 
NSInteger count = [self.fetchedResultsController.sections count]; 
if (count > 0) { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0]; 
    count = [sectionInfo numberOfObjects]; 
    if (count > 0) { 
     NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
     NSString *name = [obj valueForKey:@"name"]; 
     [obj setValue:@"X" forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
     [obj setValue:name forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
    } 
} 
관련 문제