我的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
是来自PREVIOUS获取请求的获取对象,而不是新获取的对象。也就是说,如果我做的:
// 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?
所以这个问题是在我的管理对象范围内调用。如果我从不保存数据,那么抓取请求永远不会像这样混淆,但是一旦我这样做了,就像正在保存旧的抓取请求,即使fetchedResultsController
本身仅在我的视图控制器的viewDidLoad
方法中创建。
任何人有任何想法是怎么回事?
更新:更多代码。
- (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;
}
几乎可以肯定,问题并不在于在applicationDidEnterBackground:方法中保存Managed Object Context。请发布您的viewDidLoad和fetchedResultsController方法的代码。 – 2010-12-12 18:55:34
更新了原始帖子。 – 2010-12-12 19:05:13