【问题标题】:How to deallocate RealityKit ARView()?如何释放 RealityKit ARView()?
【发布时间】:2020-05-11 12:35:37
【问题描述】:

我无法从内存中释放我的 RealityKit ARView()

我知道 ARKit + SceneKit 存在(曾经?)类似的问题 - 有这样的解决方法:https://stackoverflow.com/a/53919730/7826293 不幸的是,这并不能解决我的问题。

上述解决方案是通过手动删除所有“可疑”内容来实现的。这正是我在更广泛的范围内所做的:

class ViewController_ARViewMemoryTest: UIViewController {

    var arView: ARView?

    init() {
        super.init(nibName: nil, bundle: nil)
        arView = ARView(frame: .zero)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        doEverythingThatsNeeded()
    }

    public func doEverythingThatsNeeded() {
        self.arView?.session.pause()
        self.arView?.session.delegate = nil
        self.arView?.removeFromSuperview()
        // Quite a few more removals and resets here, ie. for Combines AnyCancellables
        self.arView = nil
    }

}

我也从外部调用 doEverythingThatsNeeded():

aRViewMemoryTest?.doEverythingThatsNeeded()
aRViewMemoryTest?.arView = nil
aRViewMemoryTest = nil

这个问题似乎与我已将我的 ARView 或 UIViewController 包装在 SwiftUI UIViewRepresentable / UIViewControllerRepresentable 中这一事实无关。

我认为这一定是一个错误,并且我已在几个月前提交了一份报告。不过,在 Apple 解决潜在问题之前,我希望能找到一些解决方法。

非常感谢!

【问题讨论】:

    标签: swift swiftui arkit realitykit


    【解决方案1】:

    这是它在 UIKit 中的外观:

    import UIKit
    import RealityKit
    
    class ViewController: UIViewController {
        
        var arView: ARView? = ARView(frame: .zero)
    
        deinit { removingView() }
        
        func addingView() {
            self.arView?.frame = .init(x: 0, y: 0, width: 300, height: 700)
            self.view.addSubview(arView!)
        }
        
        func removingView() {
            self.arView?.session.pause()
            self.arView?.session.delegate = nil
            self.arView?.scene.anchors.removeAll()
            self.arView?.removeFromSuperview()
            self.arView?.window?.resignKey()
            self.arView = nil
        }
        
        override func viewDidLoad() {
            super.viewDidLoad()            
            addingView()
            
            let boxAnchor = try! Experience.loadBox()
            arView?.scene.anchors.append(boxAnchor)
            
            removingView()
        }
    }
    

    然而,真正的问题是,当 ARView 被取消初始化时,为其分配的内存并未完全释放(即使代码 100% 正确)。但也有好消息——当你再次使用这个 ARView 时,将使用相同的分配内存。

    SwiftUI 版本:

    import SwiftUI
    import RealityKit
    
    struct ARViewContainer: UIViewRepresentable {
            
        func updateUIView(_ uiView: ARView, context: Context) {
            uiView.removeFromSuperview()
        }
    
        func makeUIView(context: Context) -> ARView {        
            let arView = ARView(frame: .zero)
            let boxAnchor = try! Experience.loadBox()
            arView.scene.anchors.append(boxAnchor)
            return arView
        }
    }
    

    【讨论】:

    • 谢谢!我没有使用体验。但除此之外,我已经将我的代码剥离为只有 AppDelegate 和你的类,加上一个将 viewController 设置为 nil 的按钮:仍然没有成功。
    • 嘿@AndyFedo,再次感谢。您能否评论一下updateUIView(_ uiView: ARView, context: UIViewRepresentableContext<ARViewContainer>) 方法在这种情况下扮演的角色?如果我在包含ARView(frame: somethingNotZero)makeUIView(context: Context) -> ARView 中启动一个空的ARView,我会看到启动会话的内存开销约为400MB。到目前为止,一切都很好。也没有成功摆脱内存消耗...
    • 嗨@Andy,你成功了吗?
    • 嗨@HelloTimo。还没有。
    • @AndyJazz SwiftUI 版本可以工作,但需要注意的是 updateUIView 可以在 ARViewContainer 需要卸载之前调用。感谢您的回答,因为它肯定有助于释放容器。
    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 2020-02-14
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 2021-04-29
    • 2020-04-28
    • 2021-09-25
    相关资源
    最近更新 更多