在StackOverflow上有许多非常相似的问题,但我问这个问题是因为几乎所有现有问题都是由于没有在FRC上调用performFetch
引起的。
在这种情况下,我们称之为。
fetchedResultsController = NSFetchedResultsController(fetchRequest: StepRecord.fetchRequest(forDate: date),
managedObjectContext: theMainThreadContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
} catch (let error) {
print(error)
}
然后在后面的函数中,我们有这样的东西......
func updateScreen() {
if fetchedResultsController.fetchedObjects.count == 0 {
// download data and store into core data
}
// update the screen
}
我们有委托方法......
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
updateScreen()
}
写入核心数据的地方肯定写入backgroundThreadContext
(这是我们在应用程序中多次使用的模式,它在其他地方工作)。
但是,在这种情况下,不会调用委托方法。
如果我们退出屏幕并返回updateScreen
方法运行并且FRC DOES有数据。因此,获取请求是正确的,下载将记录放在正确的位置并正确保存,更新屏幕方法可以获取这些项目并填充屏幕。
我们遇到的唯一问题是没有调用委托方法。
我们在这里错过了什么吗?就像我说的那样,我们在一些地方使用了相同的模式并且它有效。只是在这种情况下,它无法正常工作。
如果您有任何其他想要查看的代码,请告诉我。如果可以,我会将其传递给您。
答案 0 :(得分:0)
发生的情况是您使用不同的NSManagedObjectContext来保存下载的数据。正如您所说,该上下文使用后台队列。但也许这种背景不是FRC背景的孩子。在这种情况下,您需要合并到主上下文中,听取其他更改的通知。
但是解决它的简单方法是使用背景上下文,它是主要上下文的子项。也就是说,创建一个类型为privateQueue的新上下文,并将其parentContext设置为等于当前上下文。
答案 1 :(得分:0)
TL:DR - 不存在的对象,不会听取NSNotifications。
好的,经过一些严肃的调试后,我们终于找到了造成这个问题的问题,这很麻烦。
所以,我的问题中的代码存在于class
内部,而Consumer - view controller
- Factory - strongly referenced
- Worker - function variable
- FetchedResultsController stuff - strongly referenced
本质上是一个&#34;工作者&#34;对于工厂类。
工厂使用这个工人来创建一个对象并将其返回给工厂的所有者(&#34;消费者&#34;如果你愿意的话)。
{{1}}
虽然我们对工厂进行了强有力的参考,但工厂实际上并没有在工作所用的功能之外存储对工人的引用。
这意味着,当下载完成并将内容保存到CoreData时,Fetched Results Controller和&#34; worker&#34;实际上已不再存在于记忆中了。
因此,简单的解决方法是向工作者添加存储的引用。
更长的解决方法是重构我认为的一些代码,但那是另一天的工作。
感谢所有帮助。这无疑帮助我们解决了这个问题。