NSFetchedResultsController 不从后台上下文(DATAStack)更新

NSFetchedResultsController doesn’t update from background contexts (DATAStack)

我正在使用 NSFetchedResultsController 和 DATAStack。如果我在其他上下文中进行任何更改,我的 NSFetchedResultsController 不会更新我的 table。

我在 NSFetchedResultsController 中使用 dataStack.mainContext。如果我从 mainContext 做任何更新,一切都很好。但是如果我写这样的代码例如:

        dataStack.performInNewBackgroundContext({ (backgroundContext) in
            // Get again NSManagedObject in correct context, 
            // original self.task now in main context
            let backTask = backgroundContext.objectWithID(self.task.objectID) as! CTask

            backTask.completed = true
            let _ = try? backgroundContext.save()
        })

NSFetchedResultsController 不更新单元格。例如,如果我重新加载应用程序或整个视图,我将看到更新的数据。

数据保存没有错误(我检查过了)

我已经尝试检查是否收到 NSManagedObjectContextDidSaveNotification,但是如果我在收到通知后执行 .performFetch(),我会再次在 table 中获取旧数据。

没有很好地记录不同的背景上下文选项应该用于什么以及如何使用。可能值得提出问题/提交 PR。

您的问题是 performInNewBackgroundContext 没有将更改合并到主上下文中。这是因为没有规定上下文层次,所以你可以选择你想做什么。

因此,您可以自己监控保存和合并更改。或者您可以设置父上下文。或者您可以使用 newBackgroundContext(它会自动合并更改,尽管这有点奇怪...)。

终于搞定了,不是语境问题

我在 didChangeObject func in NSFetchedResultsControllerDelegate if NSFetchedResultsChangeType is Move 中使用了这种类型的代码(生成该事件是因为我认为的排序):

guard let indexPath = indexPath, newIndexPath = newIndexPath else { return }
_tableView?.moveRowAtIndexPath(indexPath, toIndexPath: newIndexPath)

这是不正确的(我不知道为什么 NSFetchedController 在数据更改时生成移动事件而没有“重新加载数据事件”),我用下一个代码替换了它,现在一切正常。

guard let indexPath = indexPath, newIndexPath = newIndexPath else { return }
_tableView?.deleteRowsAtIndexPaths([indexPath], withRowAnimation:   UITableViewRowAnimation.Fade)
_tableView?.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)