繁体   English   中英

NSFetchedResultController未在委托中调用controllerDidChangeContent

[英]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。

好的,经过一些认真的调试,我们终于找到了导致此问题的原因,这很麻烦。

因此,我所质疑的代码存在于一个classclass本质上是工厂类的“工人”。

工厂使用了该工人来创建对象,并将其返回给工厂的所有者(如果需要,可以称为“消费者”)。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM