使用新的backgroundContext将HTTP请求中的数据插入到CoreData中时,我遇到一个非常奇怪的崩溃:

persistentContainer.performBackgroundTask({(上下文)在
})

我的代码如下:

persistentContainer.performBackgroundTask({ (context) in
   context.perform {
       //do some insert in this context (usually there is a lot of data)
       do {
          try context.save(). <-- Crash happens here
       } catch {
          //
       }
   }
})


在主上下文中设置了我的FRC,以提供UITableView的更新。如果在ViewController中将FRC委托设置为self以便在tableView中更新UI,则每次我拉动刷新以获取新数据时都会崩溃(正是在上面所示的上下文中保存)。在线程堆栈的最上面一行写着著名的:

CoreData`+[NSManagedObjectContext __Multithreading_Violation_AllThatIsLeftToUsIsHonor__]:


真正奇怪的是,我是在NSPersistentContainer的新API之前手动执行此操作的,即创建一个私有队列上下文并侦听其保存到通知以通知主队列上下文,并且它工作得很好。现在有此崩溃。

另外,如果我在主队列上下文中插入了来自请求的数据,则一切正常。如果我继续使用performBackgroundTask函数中的背景上下文,但未在视图控制器中设置FRC的委托(因此,未获取UI更新),则同样适用。

据我所知,这是一个非常简单的实现,以前可以按预期运行,但现在不行了,我开始相信,我不能-不再-将FRC与将数据插入Core Data堆栈中的API一起使用专用队列上下文。

您能提出另一种解决方案吗?谢谢!

*如果我使用以下方法也会发生:

let context = CDManager.sharedInstance.container.newBackgroundContext()


**请求的响应在主队列中提供。

编辑
我在另一个屏幕上为另一个型号的FRC使用了完全相同的设置,并且工作正常。我要crack头了...

更新
我评论了有问题的FRC的代码,重新编写它,现在可以正常工作了……真的很奇怪。但是,谢谢您的帮助!

最佳答案

摆脱“ context.perform”。

该上下文是临时的,可能在performBackgroundTask块之外不存在。 performBackgroundTask块已经在正确的线程上运行。当您调用context.perform时,上下文可能已在代码运行时离开内存。

这并不能解释为什么获取结果控制器会出现问题。我建议检查以确保所有内容都在主线程上,或者共享该代码。

关于swift - 设置委托(delegate)Swift 4,iOS 10+时NSFetchedResultsController崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46405522/

10-12 01:49