2013-08-20 12 views
5

otrzymuję następujący komunikat o błędzie:Dziwaczny problem - „pobranego obiektu o indeksie x ma poza kolejnością nazwy sekcji”

CoreData: error: (NSFetchedResultsController) The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name' 
Unresolved search error Error Domain=NSCocoaErrorDomain Code=134060 "The operation couldn’t be completed. (Cocoa error 134060.)" UserInfo=0xaa07530 {reason=The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name'}, { 
    reason = "The fetched object at index 5 has an out of order section name 'James. Objects must be sorted by section name'"; 
} 

I już przez niezliczonych odpowiedzi na SO które najczęściej kończy się wskazując stosując cASEINSENSITIVE porównać jako odpowiedź jednak jak widać poniżej mojej pobrać wniosek jest już konfigurację, aby to zrobić:

<NSFetchRequest: 0xc082bd0> (entity: InviteeModel; predicate: (eventId == 148 AND typeOf != "InviteeTypeOfServerContact"); sortDescriptors: ((
    "(lastName, ascending, caseInsensitiveCompare:)", 
    "(firstName, ascending, caseInsensitiveCompare:)" 
)); batch size: 1000; type: NSManagedObjectResultType;) 

I wydawało się, że zmniejszyła go do przypadku, gdy mam dwie zaproszone osoby o tym samym nazwisku (tj. HENRY JAMES i Henry James), a następnie otrzymuję błąd powyżej mówiąc to James jest nieczynny. Jeśli zmienię oba nazwiska na Jamesa lub JAMESa, to działa?!?!?

Oto kod, który tworzy żądanie pobierał:

NSFetchRequest *fetchRequest = [self buildFetchRequest]; 

// We have to reset the fetched results controller if the sort changes. 
// Because otherwise the scrolling index will be inaccurate. 
if (self.fetchedResultsController) { 
    if (![self.fetchedResultsController.sectionNameKeyPath isEqualToString:self.sortBy]) { 
     self.fetchedResultsController = nil; 
    } 
} 


if (!self.fetchedResultsController) { 

    NSManagedObjectContext *context = self.event.managedObjectContext; 

    NSString *sectionNameKeyPath = nil; 
    if (self.sortBy == DefaultSortBy) { 

     sectionNameKeyPath = @"sectionChar"; 
    } 
    else { 

     sectionNameKeyPath = self.sortBy; 
     if ([self.sortBy isEqualToString:@"rsvpState"] || [self.sortBy isEqualToString:@"checkedIn"]) { 
      sectionNameKeyPath = @"lastName"; 
     } 
    } 

    NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                           managedObjectContext:context 
                           sectionNameKeyPath:sectionNameKeyPath 
                              cacheName:nil]; 
    fetchedResultsController.delegate = self; 
    self.fetchedResultsController = fetchedResultsController; 

i tutaj jest kawałek od buildFetchRequest że dodaje sortDescriptors:

 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:self.sortBy 
                     ascending:self.shouldSortAscending 
                     selector:@selector(caseInsensitiveCompare:)]; 

     // Add the default sorts (last, first). 
     NSSortDescriptor *lastSort = nil; 
     NSSortDescriptor *firstSort = nil; 
     if (![self.sortBy isEqualToString:@"lastName"]) { 
      lastSort = [NSSortDescriptor sortDescriptorWithKey:@"lastName" 
                ascending:YES 
                 selector:@selector(caseInsensitiveCompare:)]; 
     } 
     if (![self.sortBy isEqualToString:@"firstName"]) { 
      firstSort = [NSSortDescriptor sortDescriptorWithKey:@"firstName" 
                 ascending:YES 
                 selector:@selector(caseInsensitiveCompare:)]; 
     } 

     NSArray *sorts = nil; 

     if (lastSort && firstSort) { 
      sorts = [[NSArray alloc] initWithObjects:sortDescriptor, lastSort, firstSort, nil]; 
     } 
     else if (lastSort) { 
      sorts = [[NSArray alloc] initWithObjects:sortDescriptor, lastSort, nil]; 
     } 
     else { 
      sorts = [[NSArray alloc] initWithObjects:sortDescriptor, firstSort, nil]; 
     } 

     [fetchRequest setSortDescriptors:sorts]; 

Wszelkie pomysły, to doprowadza mnie do szału.

+0

Czy możesz NSLog kompletny fetchedResultsController? –

+0

@MartinR, thx za pomoc. Czy jest coś konkretnego, czego szukasz w dokumencie, który mogę wydrukować? Jest to duży obiekt i nslogowanie go daje mi tylko adres. –

+0

Moje główne pytanie dotyczy tego, czy sectionNameKeyPath i deskryptor pierwszego sortowania zawsze używają tego samego klucza. Nie jest to dla mnie oczywiste ze swojego kodu. –

Odpowiedz

2

Służy do ustawiania ścieżki klucza nazwy pobieżnej sekcji wyników, która różni się od klucza deskryptora pierwszego sortowania.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] 
      initWithKey:self.sortBy 
      ascending:self.shouldSortAscending 
      selector:@selector(caseInsensitiveCompare:)]; 

Klucz to self.sortBy.

if ([self.sortBy isEqualToString:@"rsvpState"] || 
    [self.sortBy isEqualToString:@"checkedIn"]) { 
     sectionNameKeyPath = @"lastName"; 
} 

Key jest nieself.sortBy.

Powoduje to błąd, który widzisz.

+0

Witam @Mundi, wydrukowałem wartość self.sortBy i FRC sectionNameKeyPath i zawsze jest "lastName" nawet wtedy, gdy pojawia się błąd, więc nie jestem pewien, czy to jest to? –

+0

Wydrukuj również kluczową ścieżkę pierwszego deskryptora sortowania i porównaj. – Mundi

0

Cóż, kluczową kwestią jest właściwość określająca sectionNameKeyPath i jeśli ta właściwość została użyta jako pierwszy deskryptor sortowania w tablicy deskryptorów sortowania.

Domyślam się, że to pierwsza rzecz, którą należy sprawdzić, jeśli masz problem w ten sposób.