ARSCNView зависает при добавлении 14 объектов подкласса ARAnchor со строгой ссылкой

У меня есть следующий код:

    guard let feauturePoint = frame.hitTest(normalizedPoint, types: .featurePoint).first?.worldTransform else {
        return
    }
    let anchor = MyAnchorSubclass(transform: feauturePoint, plus: someAdditionalInfo)
    arSession.add(anchor: anchor)

Эта функция создает и добавляет объект моего подкласса ARAnchor. Затем...

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let anchor = anchor as? MyAnchorSubclass else { return }
        anchors.append(anchor)
        /* then goes some my logic with adding SCNNode */
    }

... после рендеринга якоря я добавляю туда свой SCNNode. Но когда я использую anchors.append(anchor), где anchors равно [MyAnchorSubclass], сцена зависает сразу после 14 добавленных якорей. Если я не сохраняю привязку в массиве, представление сцены не зависает.

Кто-нибудь знает, что это такое? Ошибка iOS 11 Beta или какие-то ограничения?

ОБНОВЛЕНИЕ

Последнее, что происходит - вызывается renderer(_:didUpdate:for:), после чего вид сцены зависает, и в журнале появляется несколько сообщений [Technique] World tracking performance is being affected by resource constraints [0].

ОБНОВЛЕНИЕ 1

Интересный факт: после того, как приложение уходит в фон и возвращается обратно, вызываются sessionWasInterrupted(:) и sessionInterruptionEnded(:), хотя до этого представление сцены было заморожено.


person Vasilii Muravev    schedule 02.08.2017    source источник
comment
Никогда не помешает сообщить об ошибке на всякий случай. При беглом чтении я бы также предположил, что существует некоторая опасность того, что ваш якорный подкласс (возможно, косвенно) удерживает некоторые ресурсы (например, пиксельный буфер камеры), которые ARKit ожидает переработать. Кроме того, указали ли вы, где в вашем коде начинается замораживание, например. заходя в отладчик?   -  person rickster    schedule 02.08.2017
comment
@rickster Не могу сказать, в какой именно момент он зависает. Но если это произойдет после вызова renderer(_:didUpdate:node:for anchor:). И после этого я вижу несколько World tracking performance is being affected by resource constraints [0] сообщений.   -  person Vasilii Muravev    schedule 02.08.2017
comment
Являются ли эти сообщения в журнале › [Техника] На производительность отслеживания мира влияют ограничения ресурсов [0] …появляющиеся после сбоя сеанса или также до?   -  person PDK    schedule 07.08.2017
comment
@ПДК appearing after the session failed, or also before - после   -  person Vasilii Muravev    schedule 07.08.2017
comment
@VasiliiMuravev Вроде не связано, но знаете ли вы разницу в использовании ARAnchor вместо прямого добавления SCNNode?   -  person Francescu    schedule 23.11.2017


Ответы (2)


Хорошо, ваша проблема в том, что вы не хотите поддерживать свой собственный массив якорей. Вы хотите поддерживать массив идентификаторов (UUID) каждой привязки. В документах Apple:

Якоря считаются равными на основании их свойства identifier.

Причина в том, что ARKit вызывает init(anchor:) в фоновом потоке для копирования экземпляров вашего класса привязки из каждого ARFrame в следующий. При сохранении массива каждого ARAnchor вы удерживаете только один набор экземпляров этих якорей во времени, которые в противном случае были бы отброшены ARKit.

С вашим массивом UUID якорей, если вам нужно сослаться на один, переберите якоря в сеансе для текущего ARFrame, ища UUID того, с которым вам нужно что-то сделать.

Вы можете использовать что-то вроде:

func anchorForID(_ anchorID: UUID) -> ARAnchor? {

    return session?.currentFrame?.anchors.first(where: { $0.identifier == anchorID })

}
person Geoff H    schedule 28.07.2018

Кто-нибудь знает, что это такое? Ошибка iOS 11 Beta или какие-то ограничения?

Пожалуйста, реализуйте обратный вызов session(_:didFailWithError:), чтобы вы могли видеть, что ARError возвращается в случае сбоя вашего ARSessionчто приводит к зависанию экрана.


NB. если вы получите Code=200 "World tracking failed.", я бы очень хотел знать, потому что я resource-constraints">диагностика здесь.

person PDK    schedule 07.08.2017
comment
В моем случае сессия не терпит неудачу. Просто замерзает. - person Vasilii Muravev; 07.08.2017
comment
Мое представление зависло, но я заметил, что приложение не рухнуло, поэтому я реализовал session(_:didFailWithError:), а затем заметил, что зависание произошло в момент сбоя сеанса. Можете ли вы подтвердить, что он у вас реализован и он не вызывается, когда он зависает? (Если это так, то это серьезная ошибка на стороне Apple, поэтому вам обязательно нужно отправить отчет об ошибке) - person PDK; 07.08.2017
comment
session(_:didFailWithError:) не вызывается. И после того, как вы уходите на задний план и возвращаетесь обратно, все снова начинает работать. - person Vasilii Muravev; 07.08.2017