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

Posted

技术标签:

【中文标题】核心数据:为啥必须调用重新加载数据才能使我的应用程序正常工作?【英文标题】:Core Data: Why reload data must be called to make my app work?核心数据:为什么必须调用重新加载数据才能使我的应用程序正常工作? 【发布时间】:2012-09-29 23:22:40 【问题描述】:

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

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】:

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

但是没有将初始获取的结果发送到表视图的自动机制。这就是为什么你必须在performFetch 之后调用reloadData 的原因。

但是,在某些情况下,这似乎会自动运行。 UITableViewControllerviewWillAppear 中调用reloadData(如果第一次加载表)。因此,如果您在viewDidLoad 中设置FRC,则reloadData 将在viewWillAppear 中调用,您不必手动调用它。

【讨论】:

这正是我需要知道的。你帮了我很大的忙! 谢谢你们!你救了我的命!

以上是关于核心数据:为啥必须调用重新加载数据才能使我的应用程序正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我必须执行两次按钮功能才能使我的逻辑正常工作?

iOS 为啥我的应用程序在重新启动之前不会将数据加载到 tableview 中?

为啥我的函数没有重新加载 UITableView 的数据?

Flutter:为啥我的构建器在 Web 服务调用后没有重新加载?

iOS:重新加载 UITableView 后滑动显示数据

为啥添加导航控制器会使我的数组消失?