首页 > 解决方案 > 状态恢复和托管对象崩溃

问题描述

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

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

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

无论我尝试在encoderestorablestate中存储什么:with,按home,然后在xcode中停止应用程序然后在xcode中重新启动,decoderestorablestate func永远不会被调用并且在此之前因为人为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>

}()

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

我已经做了很多不同的尝试来尝试将哪些内容放入encoderestorablestate,但没有任何东西可以阻止崩溃。这似乎会出现很多,但我找不到任何信息让我感到困惑。

感谢您的时间。

标签: iosswiftcore-datastate-restoration

解决方案


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

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

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

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

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

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

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


推荐阅读