2010-10-14 11 views
18

bekomme ich folgende Fehlermeldung, wenn ein Datensatz hinzufügen möchten:Serious Anwendungsfehler in Core Data mit fetchedResultsContainer

Schwerwiegende Fehler in der Anwendung. Die Ausnahme wurde während der Kerndatenänderung Verarbeitung abgefangen. Dies ist normalerweise ein Fehler in einem Beobachter von NSManagedObjectContextObjectsDidChangeNotification. Der Index 0 ist ungültig mit userinfo (null)

Und das ist es. Ich habe Haltepunkte in alle delegiertenResultsContainer-Delegiertenmethoden eingefügt, die ich implementiert habe, aber nichts bricht.

Ich verfolgt es auf:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"titleFirstLetter" cacheName:@"Root"]; 

"sectionNameKeyPath" ist das Problem. "titleFirstLetter" ist eine vorübergehende Eigenschaft, für die ich einen Getter in meiner NSManagedObject-Unterklasse erstellt habe.

Hier ist der Getter:

-(NSString *)titleFirstLetter 
{ 
    [self willAccessValueForKey:@"titleFirstLetter"]; 
    NSString *aString = [[self valueForKey:@"title"] uppercaseString]; 

    NSString *stringToReturn = [aString substringWithRange:[aString rangeOfComposedCharacterSequenceAtIndex:0]]; 

    [self didAccessValueForKey:@"titleFirstLetter"]; 
    return stringToReturn; 
} 

Wenn ich die sectionNameKeyPath auf Null zu ändern, es funktioniert, aber es ist offensichtlich nicht das, was ich will. Es funktioniert auch, wenn ich einen Titel für mein Modell bereits ausgefüllt habe, so dass titleFirstLetter nicht null zurückgibt, obwohl das nicht ganz das Problem zu sein scheint. Wenn ich die Zeichenfolge willkürlich mache, wenn sie null ist, stürzt sie immer noch ab.

Irgendeine Idee, was ist hier oben?

UPDATE: Wenn ich den Titel in der sectionNameKeyPath anstelle der vorübergehenden Eigenschaft verwenden, stürzt es nicht ab, sondern legt offensichtlich jedes Element in einem eigenen Abschnitt. Also ist es irgendwie mit der vorübergehenden Eigenschaft verwandt ...

UPDATE2: Einige vorbereitende Hacking mit einer dauerhaften Eigenschaft anstelle von transient, und keine anderen Änderungen, scheint gut zu funktionieren, so dass dies ein Bug aussieht. Ich habe einen Fehlerbericht geöffnet: # 8553064

UPDATE3: Nun, kratzen Sie das. Die Verwendung eines persistenten Attributs machte keinen Unterschied. Ich bin jetzt etwas am Ende.

Danke!

Antwort

12

Nun, das ist wahrscheinlich teilweise (oder vollständig) Benutzerfehler. Das Problem war, dass ich in der Ansicht, in der ich einen neuen Artikel hinzufüge, [self.tableView reloadData] innerhalb der viewWillAppear Methode platziert hatte. Das zu kommentieren hat die Tabellenzellen nicht aktualisiert, aber den Absturz verhindert.

Ich ging dann voran und schickte reloadRowsAtIndexPaths:withRowAnimation: an die Tabellenansicht, um die wenigen Zellen, die es benötigten, manuell neu zu laden.

Ich bin froh, dass es endlich vorbei ist!

+0

Sparte meinen Speck! Vielen Dank! Wo hast du reloadRowsAtIndexPaths hinzugefügt: withRowAnimation :? –

+0

sehr danke. dieses Problem stört mich für lange Zeit. – derjohng

2

Das Standardverhalten des abgerufenen Ergebniscontrollers besteht darin, einen Abschnitt für jeden ersten Buchstaben des sectionNameKeyPath zu erstellen. Sie sollten nicht einen Abschnitt pro Artikel erhalten, es sei denn, jeder Artikel beginnt mit einem anderen Buchstaben.

Wenn Sie das Verhalten des Abschnittsnamens anpassen möchten, Unterklasse NSFetchedResultsController und überschreiben sectionIndexTitleForSectionName: und sectionIndexTitles. Einzelheiten finden Sie in den Dokumenten NSFetchedResultsController.

+0

Was mache ich dann hier falsch? http://assets.zerodeviation.net/sections.png Dies ist mit dem Titel als sectionNameKeyPath. – Christoph

+0

Um hinzuzufügen, sagen die Dokumente, dass der __IndexTitle__ standardmäßig der Großbuchstabe ist. Und das stimmt. Aber ich spreche von den Abschnittstiteln. – Christoph

+0

Die indexTitles sind die Titel der Abschnitte. Sehen Sie sich an, wie die Kontakt-App Namen auflistet. Es verwendet diese genau eingebaute Methode. Ich weiß nicht, warum du dieses Problem hast. Wahrscheinlich haben Sie irgendwo die Attribute durchkreuzt. – TechZen

1

Ich entdeckte einen anderen Weg, um zu dieser gleichen kryptischen Ausnahme zu gelangen. Meine vorübergehende Eigenschaft - wie die Ihre, um den ersten Buchstaben zu extrahieren - wurde nicht vor einer Zeichenfolge mit der Länge 0 (@ "") geschützt. Der Versuch, das erste Zeichen zu erhalten, verursachte eine Ausnahme und führte zu diesem Core Data-Fehler (und nicht zu der Ausnahme, die Sie erwarten würden).

2

Ich dachte, das war mein Problem. Ich hatte dieselbe Warnmeldung erhalten, aber meine Lösung war SEHR anders.

Sie können diesen Fehler erhalten, wenn Sie nicht alle NSFetchedResultsController Delegate-Methoden ordnungsgemäß implementiert haben. Ich kopiere immer einfach die 4 Methoden von Apple, um NSFetchedResultsController zu implementieren.

Leider hatte ich eine dieser verpasst:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView beginUpdates]; 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
    [self.tableView endUpdates]; 
} 

LASSEN SIE EM haben, sonst werden Sie Ihre Haare wie ich herausziehen.

+0

Ich werde nach denen Ausschau halten, danke! – Christoph

+0

Dies ist eine sehr einfache Lösung für ein häufiges Problem. Während alle anderen Antworten sicher auch richtig sind, kann dieser subtile Fehler auch den gleichen Fehler erzeugen. Nichts wert. –

0

Wichtige

NSFetchedResultsController * consultMessageFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[[[WYCoreDataStorage shareStore] coreDataHelper] mainContext] sectionNameKeyPath:nil cacheName:nil]; 

Wenn Sie einen Cache verwenden, müssen Sie deleteCacheWithName nennen: vor einer der Abrufanforderung, sein Prädikat, oder seine Art Deskriptoren zu ändern. Sie dürfen den gleichen abgerufenen Ergebniscontroller für mehrere Abfragen nicht erneut verwenden, es sei denn, Sie legen den Wert für cacheName auf null fest.