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