Mon application iPhone (4.1.2) dispose d'un menu dont chacune des entrées mène à une vue de table différente remplie par NSManagedObject
sous-classes. J'utilise le même contrôleur de vue pour chacun, mais ce qui est différent est le prédicat de la requête d'extraction, de sorte que des données différentes sont affichées en fonction de l'élément de menu choisi par l'utilisateur. Assez simple. Tout fonctionne correctement avant d'enregistrer réellement le contexte d'objet géré. Cependant, les choses vont bizarre après l'application entre l'arrière-plan et l'avant-plan pénètre à nouveau, parce que je suis en utilisant ceci:Bogue Weird Core Bug
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSError *error = nil;
if(managedObjectContext != nil)
if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
j'ai pensé que ce serait un bon moment pour enregistrer mes données. Mais après que cela est arrivé, après que j'appelle performFetch:
sur mon contrôleur de résultats récupérés, ses fetchedObjects
sont les objets récupérés de la demande de récupération PREVIOUS, et non le nouveau. Autrement dit, si je fais:
// 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?
La question est donc d'appeler save:
sur mon contexte d'objet géré. Si je n'enregistre jamais les données, les requêtes d'extraction ne sont jamais mélangées comme ça, mais une fois que je le fais, c'est comme si les anciennes requêtes d'extraction étaient sauvegardées, même si le fetchedResultsController
lui-même n'est créé que par la méthode viewDidLoad
de mon contrôleur.
Quelqu'un a-t-il une idée de ce qui se passe?
MISE À JOUR: Plus de 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;
}
Il est presque certain que le problème ne réside pas dans la sauvegarde du contexte d'objet géré dans la méthode applicationDidEnterBackground:. Veuillez publier le code de vos méthodes viewDidLoad et fetchedResultsController. –
Message original mis à jour. –