2010-12-12 98 views
1

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

几乎可以肯定,问题并不在于在applicationDidEnterBackground:方法中保存Managed Object Context。请发布您的viewDidLoad和fetchedResultsController方法的代码。 – 2010-12-12 18:55:34

+0

更新了原始帖子。 – 2010-12-12 19:05:13

回答

1

您是否在每个子视图中进行缓存,如果是的话,是否为每个缓存使用了不同的名称?

+0

我缓存什么? – 2010-12-12 20:36:19

+0

您提取的结果。在你展示的代码片段中,相关的代码是'cacheName:@“Root”];'每个FRC都可以有一个缓存名称......如果他们共享一个名字,会发生奇怪的事情 – griotspeak 2010-12-12 20:45:40

1

很难说没有看到更多的代码,但你所遇到的问题很可能是由于最初的线在你fetchedResultsController方法:

if(_fetchedResultsController) 
     return _fetchedResultsController; 

正在发生的事情是 - 只是一个猜测 - 你是重用以前_fetchedResultsController具有使用谓词在您viewDidLoad方法提取请求2.也就是说,线

[self.fetchedResultsController performFetch:nil]; 

没有实例化一个新NSFetchedResultsController为y已经设置ou认为:由于最初的两行,因此在调用fetchedResultsController时会立即返回上一个。