В приложении «Мой iPhone» (4.1.2) есть меню, каждая запись которого ведет к другому табличному представлению, заполненному подклассами NSManagedObject
. Я использую один и тот же контроллер представления для каждого, но отличается предикат запроса на выборку, поэтому отображаются разные данные в зависимости от того, какой пункт меню выбрал пользователь. Достаточно просто.
Все отлично работает, прежде чем я на самом деле сохраняю контекст управляемого объекта. Однако после того, как приложение переходит в фоновый режим и возвращается на передний план, дела идут странно, потому что я использую это:
- (void)applicationDidEnterBackground:(UIApplication*)application {
NSError *error = nil;
if(managedObjectContext != nil)
if([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
Я подумал, что сейчас подходящее время для сохранения моих данных. Но после того, как это произошло, после того, как я вызвал performFetch:
на моем контроллере полученных результатов, его fetchedObjects
являются выбранными объектами из ПРЕДЫДУЩЕГО запроса на выборку, а не новым. То есть, если я сделаю:
// 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?
Таким образом, проблема заключается в вызове save:
в контексте моего управляемого объекта. Если я никогда не сохраняю данные, запросы на выборку никогда не смешиваются, как это, но когда я это делаю, это похоже на сохранение старых запросов на выборку, даже если сам fetchedResultsController
создается только методом viewDidLoad
моего контроллера представления. 1015 *
Кто-нибудь знает, что происходит?
ОБНОВЛЕНИЕ: больше кода.
- (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;
}