Meine iPhone (4.1.2) App verfügt über ein Menü, deren Einträge jeweils zu einer anderen Tabellenansicht führen, die von Unterklassen bevölkert wird. Ich benutze für jeden den gleichen View-Controller, aber was ist das Prädikat der Fetch-Anfrage anders, so dass unterschiedliche Daten angezeigt werden, je nachdem, welchen Menüpunkt der Benutzer gewählt hat. Einfach genug.Weird Core Data Bug
Alles funktioniert gut, bevor ich tatsächlich den verwalteten Objektkontext speichern. Doch die Dinge seltsam nach der App, den Hintergrund und tritt wieder in den Vordergrund tritt, weil ich das bin mit:
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSError *error = nil;
if(managedObjectContext != nil)
if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
Ich dachte, dies wäre eine angemessene Zeit, um meine Daten zu speichern. Aber nachdem dies passiert ist, nachdem ich performFetch:
auf meinem abgerufenen Ergebniscontroller aufgerufen habe, sind fetchedObjects
die abgerufenen Objekte aus der PREVIOUS-Abrufanforderung und nicht die neue Abfrage. Das heißt, wenn ich tun:
// Choose menu item 1
[self.fetchedResultsController performFetch:nil]; // With fetch request 1
NSLog(@"%i objects were fetched", [[self.fetchedResultsController fetchedObjects] count]); // Items for fetch request 1
// Go back to menu, choose menu item 2 for new fetch request
[self.fetchedResultsController performFetch:nil]; // Fetch request 2
NSLog(@"%i objects were fetched", [[self.fetchedResultsController fetchedObjects] count]); // Items for Fetch request 2
// Hit home button, applicationDidEnterBackground: is called
// Relaunch
// Choose menu item 1
[self.fetchedResultsController performFetch:nil]; // With fetch request 1
NSLog(@"%i objects were fetched", [[self.fetchedResultsController fetchedObjects] count]); // Items for fetch request 2 - HUH?
So ist das Problem mit save:
auf meinem verwalteten Objektkontext aufgerufen wird. Wenn ich nie Daten speichere, werden die Fetch-Anfragen niemals so durcheinander gebracht, aber sobald ich das tue, werden alte Fetch-Anfragen gespeichert, obwohl die fetchedResultsController
selbst nur mit der Methode viewDidLoad
des View-Controllers erstellt wird.
Wer hat eine Idee was los ist?
UPDATE: Mehr Code.
- (void)viewDidLoad {
delegate = (MAAppDelegate *)[[UIApplication sharedApplication] delegate];
managedObjectContext = delegate.managedObjectContext;
[self.fetchedResultsController performFetch:nil];
NSUInteger count = [[self.fetchedResultsController fetchedObjects] count]; // Bug is detected here
// ...
}
- (NSFetchedResultsController *)fetchedResultsController {
if(_fetchedResultsController)
return _fetchedResultsController;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tweet" inManagedObjectContext:managedObjectContext];
NSPredicate *predicate = nil;
if([self.navigationItem.title isEqualToString:@"Personal"])
predicate = [NSPredicate predicateWithFormat:@"account.username = %@ AND user.username = %@", delegate.currentAccount.username, delegate.currentAccount.username];
else if([self.navigationItem.title isEqualToString:@"Favorites"])
predicate = [NSPredicate predicateWithFormat:@"account.username = %@ AND favorited = YES", delegate.currentAccount.username];
else
predicate = [NSPredicate predicateWithFormat:@"account.username = %@", delegate.currentAccount.username];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
[fetchRequest setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"tweetID" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"retrieved"
cacheName:@"Root"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return _fetchedResultsController;
}
Fast sicher liegt das Problem nicht darin, den verwalteten Objektkontext in der applicationDidEnterBackground: -Methode zu speichern. Bitte geben Sie den Code Ihrer Methoden viewDidLoad und fetchedResultsController ein. –
Ursprünglicher Beitrag aktualisiert. –