Почему пользовательский интерфейс зависает при закрытии ViewController с помощью ARSCNView?

Я запускаю сеанс ARKit, в котором размещаю узлы SceneKit. С каждым узлом я создаю экземпляр нового контроллера представления и передаю его представление как содержимое узла следующим образом:

func createTextNode(anchor: ARCardAnchor) -> SCNNode? {
    let plane = SCNPlane()
    plane.height = 0.5
    plane.width = 0.5

    let sb = UIStoryboard(name: "Main", bundle: nil)
    let fCVC = sb.instantiateViewController(withIdentifier: "CardViewController") as! CardViewController


    plane.firstMaterial?.diffuse.contents = fCVC.view
    let cardNode = SCNNode(geometry: plane)
    cardNode.constraints = [billboardConstraint]
    return cardNode
}

Я добавляю узлы в сцену, используя следующий метод ARSCNViewDelegate и свой собственный ARCardAnchor (подкласс ARAnchor):

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    if let fcanchor = anchor as? ARCardAnchor {
        DispatchQueue.main.async {
            guard let n = self.nodeCreator.createTextNode(anchor: fcanchor) else { return }
            node.addChildNode(n)

        }
    }
}

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

@IBAction func goBackToPrevious(_ sender: Any) {
    sceneView.session.pause()
    self.performSegue(withIdentifier: "unwindToPrevious", sender: self)
}

и контроллер навигации, где я извлекаю контроллер сцены AR из стека. Каждый раз, когда предыдущие контроллеры представления замораживаются. Ошибок в Xcode нет, приложение продолжает работать. Если я подожду ок. Через 2 минуты я снова могу пользоваться экраном. Если я не добавляю узлы с контроллерами представления в свою AR-сцену, все работает отлично. Мое единственное объяснение заключается в том, что UIThread перегружается при добавлении узлов, потому что где-то возникает массивная утечка памяти (которую я не обнаружил, несмотря на 10 часов отладки). Кто-нибудь имел подобный опыт и может сказать мне, как это решить? Что я могу сделать, чтобы отладить это и обеспечить плавную навигацию?


person Sebastian    schedule 03.02.2019    source источник
comment
Вы пробовали использовать инструменты? Распределения/утечки были бы полезны здесь.   -  person Tomasz Pe    schedule 04.02.2019
comment
Да, я использовал основную проверку потока, а также ведение журнала Malloc Stack. Я просто вижу, что средство проверки основного потока сообщает мне, что я вызываю пользовательский интерфейс из фонового потока. Это происходит и со всеми другими приложениями ARKit и не приводит к такой же проблеме. Так что, похоже, это проблема на стороне Apple.   -  person Sebastian    schedule 04.02.2019


Ответы (2)


Проблема заключалась в том, что я назначил свои пользовательские представления UIViewController непосредственно плоскостям узлов. Я предполагаю, что это создало циклы ссылок, поскольку контроллеры представления содержали ссылки на объекты, которые я использовал в других местах сцены. Я решил это, захватив изображение представления и назначив его узлу. Похоже, что обычно опасно назначать UIViews непосредственно узлам, потому что это вызывает циклы ссылок. Может быть, кто-то более квалифицированный в вопросах памяти и/или SceneKit может высказать свое мнение по этому поводу.

person Sebastian    schedule 04.02.2019

person    schedule
comment
Не могли бы вы объяснить, как ваш код решает проблему OP? Это действительно улучшит ваш ответ. - person Aimery; 19.11.2019
comment
@Aimery Я думаю, что всякий раз, когда UIView напрямую подключен к SCNMaterial, а этот SCNMaterial к SCNNode. SCNMaterial все еще используется при посещении предыдущего экрана. Сброс ARSCNView, кажется, решает проблему. - person user12396080; 19.11.2019
comment
Большой! Просто отредактируйте свой ответ, чтобы включить объяснение, пожалуйста :) - person Aimery; 19.11.2019
comment
@Эймери Хорошо. Спасибо - person user12396080; 19.11.2019