NSFetchedResultsController 总是包含临时对象

Posted

技术标签:

【中文标题】NSFetchedResultsController 总是包含临时对象【英文标题】:NSFetchedResultsController always including temporary objects 【发布时间】:2016-01-21 18:25:48 【问题描述】:

我有一个NSFetchedResultsController,我设置如下:

        let fetchRequest = NSFetchRequest(entityName: "Order")
        fetchRequest.includesPendingChanges = false
        fetchRequest.sortDescriptors = [
            NSSortDescriptor(key: "status", ascending: false),
            NSSortDescriptor(key: "date", ascending: false)]

        self.fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: DataStoreManager.sharedInstance.mainContext,
            sectionNameKeyPath: "section",
            cacheName: nil)

        do 
            try self.fetchedResultsController.performFetch()

         catch let error as NSError 
            print(error)
        

问题是即使 includesPendingChanges 设置为 false,每次我在上下文中创建新对象(不保存)时,它仍然会调用 controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?)

为了避免这种情况,我应该寻找其他方法吗?

【问题讨论】:

有趣。如果您直接执行 fetch 请求而不是将其传递给 FRC,会发生什么?你还在获取未保存的对象吗?一种解决方法是在单独的子上下文中创建新对象,并且在您准备好之前不要保存到 mainContext。 跟踪更改——这正是 FRC 的重点。我想它只是忽略了includesPendingChanges。如果您不需要这些更改 - 只需执行一次 fetch,您将获得一个不错的不可变 NSArray 【参考方案1】:

推荐的方法是使用子上下文。父级应该是在获取的结果控制器中使用的主线程托管对象上下文。

如果您保存,更改会立即“推送”到主上下文,即获取的结果控制器。 (保存主上下文以持久化存储。)

如果您不想保存,只需丢弃子上下文而不保存。获取的结果控制器永远不会知道它。

【讨论】:

是的。但是 OP 正确地使用了includesPendingChanges,AFAICT。我找不到 NSFRC 忽略其获取请求中的该设置的文档。 文档说 includesPendingChanges 适用于 NSFetchRequest。 OP 指的是NSFetchedResultsControllerDelegate 回调。 你说在我创建一个新对象时要这样做,对吧?实际上,我一直在尝试对我创建的每个对象执行类似的操作(使用子上下文),但是当我有强制关系但无法在保存之前创建关系时,我总是遇到问题,因为对象是在不同的情况下。 您需要从您创建新对象的 same 上下文中获取另一个对象(您想要设置的关系)。这是唯一的方法,否则无论如何它都不应该工作。 @Mundi:很好,会尝试这样做。

以上是关于NSFetchedResultsController 总是包含临时对象的主要内容,如果未能解决你的问题,请参考以下文章

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