[英]NSFetchedResultController not calling controllerDidChangeContent in delegate
在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具有数据。 因此,提取请求正确无误,下载将记录放置在正确的位置并正确保存,并且更新屏幕方法能够获取这些项目并填充屏幕。
我们这里唯一的问题是未调用委托方法。
这里有我们想念的东西吗? 就像我说的那样,我们在一些地方使用了相同的模式,并且有效。 只是在这种情况下它不起作用。
让我知道您是否还想查看其他代码,如果可以的话,我会通过。
发生的情况是您正在使用其他NSManagedObjectContext保存下载的数据。 如您所说,该上下文使用后台队列。 但是,这种情况可能不是FRC的背景。 在这种情况下,您需要合并到主上下文中,以侦听其他更改的通知。
但是,解决此问题的简单方法是使用作为主要上下文子级的背景上下文。 也就是说,创建一个类型为privateQueue的新上下文,并将其parentContext设置为等于当前上下文。
TL:DR-不存在的对象将不会监听NSNotifications。
好的,经过一些认真的调试,我们终于找到了导致此问题的原因,这很麻烦。
因此,我所质疑的代码存在于一个class
, class
本质上是工厂类的“工人”。
工厂使用了该工人来创建对象,并将其返回给工厂的所有者(如果需要,可以称为“消费者”)。
Consumer - view controller
- Factory - strongly referenced
- Worker - function variable
- FetchedResultsController stuff - strongly referenced
虽然我们一直对Factory保持强烈的引用,但是工厂实际上并没有在其使用的功能之外存储对worker的引用。
这意味着,当下载完成并将内容保存到CoreData中时,Fetched Results Controller和“ worker”实际上不再存在于内存中。
因此,简单的解决方法是将存储的引用添加到工作程序。
较长的修复方法是重构我认为的某些代码,但这是另一天的工作。
感谢您的所有帮助。 它无疑帮助我们消除了问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.