状态恢复和托管对象崩溃

Posted

技术标签:

【中文标题】状态恢复和托管对象崩溃【英文标题】:State Restoration and Managed Objects Crashing 【发布时间】:2018-05-31 16:34:23 【问题描述】:

我自己无法找到任何对这个主题有帮助的信息,而且我有点新手和自学成才,因此对任何无知表示歉意。我正在制作一个联系人风格的应用程序,允许您记录与特定人员的访问。我正在使用 Core Data 来存储数据,并具有将 Person 实体链接到 Visit 实体的一对多关系。

当我从主要联系人列表中选择一个特定的人时,我将 Person 的 nsmanagedobject 传递给新的视图控制器,并在获取我对该人进行的访问时将其用作我的谓词。

此时问题出在状态恢复。我希望能够返回到这个人的页面(以及整个应用程序中的其他一些实例,但这个例子涵盖了这个问题)但是因为我通过 segue 传递了 Person 对象,所以该对象现在为零,这导致我应用程序崩溃两次,然后它启动到主屏幕,似乎要清除和恢复数据。

无论我尝试在 encoderestorablestate:with 中存储什么,按 home,然后在 xcode 中停止应用程序,然后在 xcode 中重新启动,decoderestorablestate 函数永远不会被调用,并且在此之前由于 person 为 nil 而崩溃。

下面是我的 fetchedresultscontroller,崩溃发生在谓词行 self.person 是 nil

 lazy var fetchedResultsController: NSFetchedResultsController<Visit> = 

    // Initialize Fetch Request
    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "Visit")
    // Add Sort Descriptors
    let predicate = NSPredicate(format: "person == %@", self.person!)
    fetchRequest.predicate = predicate

    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    fetchRequest.sortDescriptors = [sortDescriptor]

    // Initialize Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

    // Configure Fetched Results Controller
    fetchedResultsController.delegate = self

    return fetchedResultsController as! NSFetchedResultsController<Visit>

()

我将重申这一切都可以完美运行,并且在从顶部使用应用程序时按预期运行,它只会在尝试恢复状态时崩溃。

我已经尝试了很多不同的尝试来设置编码器可存储状态,但没有任何东西可以阻止崩溃。这似乎会出现很多,但我找不到任何信息让我感到困惑。

感谢您的宝贵时间。

【问题讨论】:

【参考方案1】:

您没有提供足够的信息来追踪问题,但这里是查看问题的一般方法。分三个部分考虑这个问题:

您有一个实现viewController(withRestorationIdentifierPath:coder:) 的恢复类。这是配置您提供的视图控制器的机会。

视图控制器发送decodeRestorableState(with:)。这是配置视图控制器的另一个机会。请注意,这是在 viewDidLoad 之后发生的。

视图控制器发送applicationFinishedRestoringState。这是您配置视图控制器的最后机会。

现在让我们考虑如何更新此视图控制器上的界面。时机很棘手,因为你不知道时机是什么。特别是,您可能在viewDidLoad 中有代码假定所有属性都已设置,并相应地配置接口。但在这种情况下,它们可能没有被设置。

因此,要使状态恢复正常工作,您需要重写您的 viewDidLoad 代码,以不假设是否已设置属性。

在你的情况下,那将是self.person。在viewDidLoad 中,您需要检查self.person,如果是nil,请不要尝试将获取的结果设置为控制器。然后applicationFinishedRestoringState 出现,现在您可能已经配置了self.person(在您的decodeRestorableState 中),您可以通过获取的结果控制器更新界面。

【讨论】:

以上是关于状态恢复和托管对象崩溃的主要内容,如果未能解决你的问题,请参考以下文章

类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们的问题的解决方法

对“xxx”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃损坏和数据丢失。向非托管代码传递委托时,托管应用程序必须让这些委托保持活动状态,直到确信不会再次调用它们。 错误解决一例。(代码片段

保存/恢复android webview的状态

C++ 中的崩溃恢复

如何保存和恢复作为音频单元主机的音频单元状态

如何保存 - 恢复所有 opengl 状态变量