2010-02-11 5 views
5

Ich verwende einen NSFetchedResultsController, um die Anzeige abgeholter verwalteter Objekte in einer Tabellenansicht mit einem Abschnitt zu verwalten. Die Tabelle beginnt leer und der Benutzer kann über die Benutzeroberfläche neue Entitäten hinzufügen. So wie es aussieht, funktioniert das Programm immer beim Hinzufügen der ersten Entity und stürzt immer beim Hinzufügen einer Sekunde ab. Es gibt manchmal keinen Fehler beim Absturz und manchmal gibt es Fehler unterschiedlicher Art (einige sind unten enthalten). Durch Log-Statements und Tracing sehe ich, dass das Programm direkt nach dem ControllerWillChangeContent des NSFetchResultsController-Delegaten (der die Methode [self.tableView beginUpdates;) aufruft] abstürzt, bevor irgendeine andere Methode in meinem Code aufgerufen wird. Hier sind einige der relevanten Teile meines Codes. Konfigurieren des NSFetchedResultsController:NSFetchedResultsController-basierte Tabellenansicht schlägt immer auf SECOND-Einfügung der Entität

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Beer" 
            inManagedObjectContext:self.managedObjectContext]]; 

// Configure request's entity and predicate 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES]; 
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 
[sortDescriptor release]; 
[sortDescriptors release]; 

NSString *expression = [NSString stringWithFormat:@"brewery.name LIKE \"%@\"", self.brewery.name]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:expression]; 
[fetchRequest setPredicate:predicate]; 
self.resultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                  managedObjectContext:self.managedObjectContext 
                   sectionNameKeyPath:nil 
                     cacheName:nil]; 
self.resultsController.delegate = self; 
[fetchRequest release]; 

NSError *error = nil; 
BOOL success = [resultsController performFetch:&error]; 
if (!success) { 
    NSLog(@"Error fetching request %@", [error localizedDescription]); 
} 

neue Einheit hinzu:

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Beer" inManagedObjectContext:self.managedObjectContext]; 
Beer *beer = [[Beer alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext]; 
beer.name = beerName; 
beer.brewery = self.brewery; 

Ich habe die Warnungen in der Dokumentation über Probleme gesehen Tabellen mit einem Abschnitt anzeigt, und ich habe Apples Abhilfe für die ohne Erfolg verwendet. Diese Methoden werden sowieso nicht vor dem Absturz aufgerufen.

Einige der Fehler, die ich erhalten haben:

Serious application error. Exception was caught during Core Data change processing: *** -[NSCFString compareObject:toObject:]: unrecognized selector sent to instance 0x4e808c0 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer compareObject:toObject:]: unrecognized selector sent to instance 0x4e53b80 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[UITextTapRecognizer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4ca5d70 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[CALayer controllerWillChangeContent:]: unrecognized selector sent to instance 0x4e271a0 with userInfo (null) 
Serious application error. Exception was caught during Core Data change processing: *** -[NSCFNumber countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x4c96ee0 with userInfo (null) 

Wie Sie sehen können, die Fehler (wenn man vorgestellt wurde) nicht konsistent sind, selbst wenn keine Änderung am Code vorgenommen wurde.

Kann jemand herausfinden, was ich falsch mache?

+0

Ich habe genau denselben Fehler. Können Sie mir sagen, was Sie getan haben, um das Problem zu lösen? Vielen Dank. – zsong

Antwort

4

Ihre inkonsistenten Fehler deuten auf ein mögliches Problem mit zu großer Freigabe hin. Zumal das Ändern der Delegierten zum erneuten Laden der Daten das Problem beseitigt. Persönlich würde ich die Zeit investieren, um das Problem zu lösen, anstatt es zu programmieren, da Sie definitiv ein Code-Problem haben, das wahrscheinlich später irgendwo anders auftauchen wird.

Ich würde folgendes tun:

  1. Schalten Sie NSZombie
  2. einen Haltepunkt hinzu objc_exception_throw
  3. Run im Debugger

Wenn die Ausnahme auftritt, sehen Sie die Speicheradresse und sehen, was zugegriffen wird und wo. Dies wird das Problem isolieren und Ihnen sagen, was vor sich geht. Es wäre auch hilfreich, wenn Sie die NSFetchedResultsController Delegiertenmethoden nicht posten könnten, damit ich sehen kann, ob etwas in ihnen seltsam ist.

Am besten, um die ursprüngliche Frage mit den zusätzlichen Informationen zu aktualisieren.

1

Ihr Code zum Erstellen neuer Entitäten ist alles seltsam. Was stattdessen mit diesem Thema:

Beer* beer = [NSEntityDescription insertNewObjectForEntityForName: @"Beer" 
    inManagedObjectContext: self.managedObjectContext]; 
beer.name = @"Grolsch"; 

Auch rufen Sie nicht NSManagedObjectContext#save:. Aber vielleicht tust du das in einem Teil deines Codes, den du jetzt gezeigt hast?

+0

Die beiden Methoden zum Erstellen der neuen Entität sind äquivalent. Das Speichern des ManagedObjectContext hat auch keine Auswirkungen auf das Problem. –

1

Während ich dieses spezielle Problem nicht gelöst habe, habe ich einen etwas anderen Ansatz gewählt, um die Klasse zu schreiben, die die gewünschte Funktionalität bietet und nicht das Problem verursacht hat. Ich benutze immer noch NSFetchedResultsController, aber anstatt alle vier Delegate-Methoden zu implementieren, implementiere ich nur ControllerDidChangeContent :, die nur [tableView reloadData] aufruft.

Dies ist die Implementierung, die in der RootViewController-Klasse enthalten ist, wenn Sie eine neue navigationsbasierte Anwendung in XCode erstellen, die Core Data für den Speicher verwendet. Sie verlieren wahrscheinlich etwas Kontrolle über Tabellen-Animationen, aber es ist viel einfacher und funktioniert gut für meine Zwecke.

0

Dies ist ein alter aber zum Vorteil von anderen mit dem gleichen Problem, habe ich stundenlang versucht zu verstehen, was los war und endlich ein Problem mit meinem Sortierungsdeskriptor gefunden, der diese zufälligen Abstürze verursachte.

Die Fehlermeldungen unterschieden sich, waren aber meistens mit einem compareObject: toObject-Selektor wie unten verwandt.

- [_ NSCFSet compareObject: toObject:]: Unbekannter Selektor zum Beispiel gesendet - [ _NSCFString compareObject: toObject:] Unbekannter Selektor an Instanz gesendet

Mein Vorschlag aller Art Deskriptoren zu versuchen und zu beseitigen und Prädikate aus Ihrem Code und fügen Sie sie dann einzeln hinzu, um das Problem zu finden.

Viel Glück! Rog

1

Ich hatte ein ähnliches Bug vor kurzem - Ihr Problem ist, mit über die Freigabe, vor allem:

[sortDescriptors release]; 

Sie erhalten die sortDescriptors von

Objekt
[NSArray arrayWithObjects:sortDescriptor, nil]; 

, die nicht "alloc" hat , "Kopieren" oder "Neu", so dass ein automatisch freigegebenes Objekt zurückgegeben wird. Weil Sie es früh freigeben, erhalten Sie zwei Stellen, an denen Sie abstürzen können - wenn NSFetchRequest es verwendet und wenn es vom Pool freigegeben wird. Weitere Informationen finden Sie unter memory management guide von Apple.

Verwandte Themen