Восстановление состояния и сбой управляемых объектов

Мне не удалось найти какую-либо информацию, которая была бы полезна для этой темы, и я несколько новичок и самоучка, поэтому приношу свои извинения за любое невежество. Я делаю приложение в стиле контактов, которое позволяет записывать посещения, совершенные с конкретным человеком. Я использую Core Data для хранения данных и имею отношение «один ко многим», связывающее сущность Person с сущностью Visit.

Когда я выхожу из основного списка контактов, выбирая конкретного человека, я передаю этот nsmanagedobject Person новому контроллеру представления и использую его в качестве своего предиката при получении информации о посещениях, которые я совершил для этого человека.

На данный момент возникает вопрос о восстановлении состояния. Я хочу иметь возможность вернуться на страницу этого человека (и несколько других экземпляров в приложении, но этот пример охватывает проблему), но поскольку я передал объект Person через переход, этот объект теперь равен нулю, что приводит к моему Приложение дважды аварийно завершает работу, затем оно запускается на главный экран, где появляется сообщение об очистке и восстановлении данных.

Независимо от того, что я пытаюсь сохранить в encoderestorablestate:with, нажмите домой, затем остановите приложение в xcode, а затем перезапустите в xcode, функция decoderestorablestate никогда не вызывается и вылетает из-за того, что перед этим человек был равен нулю.

Ниже мой fetchedresultscontroller, и сбой происходит в строке предиката, говорящей, что self.person равен нулю

 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, но ничто не остановило сбой. Это кажется чем-то, что всплывет часто, но отсутствие какой-либо информации меня смутило.

Спасибо за уделенное время.


person squiDcookiE    schedule 31.05.2018    source источник


Ответы (1)


Вы не предоставили достаточно информации, чтобы отследить проблему, но вот общий взгляд на проблему. Рассмотрим вопрос в трех частях:

  • У вас есть класс восстановления, который реализует viewController(withRestorationIdentifierPath:coder:). Это возможность настроить контроллер представления, который вы предоставляете.

  • Контроллер представления отправляется decodeRestorableState(with:). Это еще одна возможность настроить контроллер представления. Обратите внимание, что это идет после viewDidLoad.

  • Контроллер представления отправляется applicationFinishedRestoringState. Это ваша последняя возможность настроить контроллер представления.

Теперь давайте подумаем, как вы собираетесь обновлять интерфейс этого контроллера представления. Время сложно, потому что вы не знаете, какое время будет. В частности, у вас может быть код в viewDidLoad, который предполагает, что все свойства установлены, и соответствующим образом настраивает интерфейс. Но в данной ситуации они, вероятно, не установлены.

Таким образом, чтобы восстановление состояния работало, вам нужно переписать код viewDidLoad, чтобы не делать предположений о том, были ли заданы свойства.

В вашем случае это будет self.person. В viewDidLoad вам нужно проверить self.person и, если это nil, пока не пытайтесь сделать ваш контроллер полученных результатов. Затем появляется applicationFinishedRestoringState, и теперь вы, вероятно, настроили self.person (в своем decodeRestorableState) и можете обновить интерфейс через полученный контроллер результатов.

person matt    schedule 31.05.2018