2010-12-12 7 views
1

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; 
} 
+0

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. –

+0

Ursprünglicher Beitrag aktualisiert. –

Antwort

1

Zwischenspeichern Sie in jeder Teilansicht und verwenden Sie für jeden Cache einen anderen Namen?

+0

Bin ich Caching was? –

+0

Ihre abgerufenenErgebnisse. In dem Code-Snippet, das du zeigst, ist der entsprechende Code 'cacheName: @" Root "];' jeder FRC kann einen Cache-Namen haben ... seltsame Dinge können passieren, wenn sie einen Namen teilen – griotspeak

1

Es ist schwer, ohne zu sehen, zusätzlichen Code zu sagen, aber das Problem, das Sie erleben ist wahrscheinlich auf die ersten Zeilen in Ihrer fetchedResultsController Methode:

if(_fetchedResultsController) 
     return _fetchedResultsController; 

Was passiert ist, dass - nur eine Vermutung - Sie sind die vorherige _fetchedResultsController Wiederverwendung der hat gewesen Setup das Prädikat Verwendung für Abrufanforderung 2. das heißt, in Ihrer viewDidLoad Methode, um die Linie

[self.fetchedResultsController performFetch:nil]; 

ist kein neues NSFetchedResultsController als y Instanziieren ou denken: der vorherige wird sofort zurückgegeben, wenn fetchedResultsController aufgerufen wird, aufgrund der ersten zwei Zeilen.