核心数据:为什么必须调用重新加载数据才能使我的应用程序正常工作?

时间:2012-09-29 23:22:41

标签: ios core-data

我整晚都在调试一个简单的应用程序。该应用程序从Web检索一个图像(是一个...以使我的生活更轻松),并在表格视图中显示它。我这样做是为了学习核心数据。在我修复它之前,错误消息显示如下:

  

2012-09-30 06:16:12.854缩略图[34862:707] CoreData:错误:严重   应用程序错误。从代表处获得了一个例外   NSFetchedResultsController在调用期间   -controllerDidChangeContent :.无效更新:无效的节数。表视图中包含的节数   更新(1)必须等于包含的部分数   更新前的表视图(0),加号或减号   插入或删除的部分(插入0,删除0)。用户信息   (空)

基本上它是说 FRC委托方法出错了。一方面,节号从0变为1.另一方面,“0插入,0删除”。那么节号如何增加呢?这应该不会发生..因此错误。

我通过[self.tableView reloadData]添加到我的FRC设置方法来修复错误。我从这个post得到了灵感,但我不太明白。答案似乎过于复杂和具体项目。有人可以解释为什么添加reloadData可以修复错误吗?答案可能很简单,我希望如此。

我的应用的关键组件,如果重要:

  • 使用UIManagedDocument建立核心数据堆栈
  • 创建帮助方法以从Flickr API下载图像
  • 在NSManagedObject子类文件中,尝试从持久存储中获取图像。如果还没有,请将其插入MOC。

    - (void)setupFetchedResultsController
    {
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"BigImage" inManagedObjectContext:self.document.managedObjectContext];
        [fetchRequest setEntity:entity];
    
        NSSortDescriptor *imageDescriptor = [[NSSortDescriptor alloc] initWithKey:@"image" ascending:YES];
        NSArray *sortDescriptors = [NSArray arrayWithObject: imageDescriptor];
        [fetchRequest setSortDescriptors:sortDescriptors];
    
        [fetchRequest setFetchBatchSize:20];
    
        // Create fetch results controller
        self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.document.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    
        self.fetchedResultsController.delegate = self;
    
        NSError *error;
        if (![self.fetchedResultsController performFetch:&error])
        {
            NSLog(@"Error in performFetch: %@, %@", error, [error userInfo]);
        }
    
        // Critical!! I add this line to fix the bug!
            [self.tableView reloadData];
        }
    

1 个答案:

答案 0 :(得分:7)

获取的结果控制器仅跟踪第一次提取后对托管对象内容的更改。然后使用委托方法didChangeSectiondidChangeObject等将这些更改传播到表视图。

但是没有自动机制将初始提取的结果发送到表视图。这就是您必须在reloadData之后致电performFetch的原因。

然而,有一种情况似乎会自动发挥作用。 UITableViewControllerreloadData中调用viewWillAppear(如果第一次加载表格)。因此,如果您在viewDidLoad中设置FRC,reloadData将在viewWillAppear中调用,您无需手动调用。