NSFetchedResultsController“无法在-performFetch之前访问获取的对象:”调用objectAtIndexPath时崩溃:

Posted

技术标签:

【中文标题】NSFetchedResultsController“无法在-performFetch之前访问获取的对象:”调用objectAtIndexPath时崩溃:【英文标题】:NSFetchedResultsController "cannot access fetched objects before -performFetch:" crash when calling objectAtIndexPath: 【发布时间】:2017-02-10 14:41:01 【问题描述】:

在我的崩溃日志中,我发现了一个有趣的崩溃,我无法弄清楚它为什么会发生。我也无法复制它。

当用户点击一个单元格时,在我的tableView:didSelectRowAtIndexPath: 方法实现中的以下行中,它崩溃了:

fetchedResultsController?.objectAtIndexPath(indexPath) as! SearchResultEntity

崩溃:

Fatal Exception: NSInvalidArgumentException
cannot access fetched objects before -performFetch:

问题是 performFetch: 在视图控制器的 viewDidLoad 方法中被调用。因此,在调用tableView:didSelectRowAtIndexPath: 委托方法之前,不可能没有调用performFetch:。还是这样?

我在 NSFetchedResultController 中使用非常常见的设置,它显示来自数据库的结果。随着旧记录的删除和新记录的插入,数据库中的记录经常发生变化。

我想到的一件事是,当从 CoreData 中删除其相关对象并且表格视图正在动画删除更改时,用户可以点击单元格。这可能吗?

如果是这个原因,有什么办法可以避免吗?

【问题讨论】:

【参考方案1】:

是的,您可能会从 fetchedResultsController 访问删除对象,但这种情况非常罕见,而且这里没有发生这种情况。通常,NSFetchedResultController's 作业与核心数据同步。但是可能有一个非常小时间点,就像更新到来但在 fetchedResultsController 有机会更新之前访问 fetchedObject 可能导致崩溃的地方。但它不会导致performFetch 没有被调用的崩溃。

查看您的日志(如果没有,则创建日志)以查找 performFetch 失败并出现错误。如果用户的磁盘空间非常低,则可能会发生这种情况。 检查fetchedResultsController 是否被另一个fetchedResultsController 替换,执行获取的操作未被调用。 查看 viewDidLoad 中是否有任何 if 语句可能导致 performFetch 无法被调用。即使期望这些陈述总是正确的,也可能存在不正确的情况。 如果您随时在 viewController 中设置 self.view = nil,这可能会导致再次调用 viewDidLoad,这可能会导致您的应用出现意外行为。

【讨论】:

【参考方案2】:

我知道这是一个老问题,但我认为今天同样的问题困扰着我:

我有一个 UITableviewcontroller 的设置,它的 UISearchView 可用于搜索实体。这是通过使用 NSFetchResultsController 在后台线程中使用更新的 FetchRequest 谓词在每次击键时查询核心数据并在成功请求后重新加载 tableview 来完成的。

搜索并单击一个条目后,返回列表并再次快速单击任何项​​目后,我得到完全相同的错误。这是因为 UISearchView 显然在 viewDidAppear 上触发了对updateSearchResults(for searchController) 的调用,从而导致 NSFetchedResultsController 的performFetch。在 fetch 开始和 tableview 中(未更改)行的不可见重新加载之间的短暂时间范围内,单击它们会导致上述错误。

【讨论】:

以上是关于NSFetchedResultsController“无法在-performFetch之前访问获取的对象:”调用objectAtIndexPath时崩溃:的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?