奇怪的核心数据错误

时间:2010-12-12 18:12:29

标签: iphone ios core-data nsfetchedresultscontroller

我的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?

所以问题是在我的托管对象上下文中调用save:。如果我从不保存数据,那么获取请求永远不会像这样混淆,但是一旦我这样做,就像保存旧的获取请求一样,即使fetchedResultsController本身仅在我的视图控制器{{1}创建方法。

任何人都知道发生了什么事?

更新:更多代码。

viewDidLoad

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

在没有看到其他代码的情况下很难分辨,但您遇到的问题可能是由于fetchedResultsController方法中的初始行:

if(_fetchedResultsController)
        return _fetchedResultsController;

正在发生的事情 - 只是一个猜测 - 您正在重复使用谓词提取请求2设置的先前_fetchedResultsController。也就是说,在您的viewDidLoad方法中行

[self.fetchedResultsController performFetch:nil];

没有按照您的想法实例化新的NSFetchedResultsController:由于最初的两行,在调用fetchedResultsController时会立即返回前一个{{1}}。