为什么 RealityKit 内存在 deinit 调用后没有清除?

Why does RealityKit memory does not clear after deinit called?

我无法从内存中释放我的 RealityKit ARView()。不幸的是,我知道 ARKit + SceneKit 的变通办法不能解决我的问题。

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

func closeCurrentView(completion: (() -> Void)? = nil, isScanAnotherFloor: Bool = false) {
    if backgroundRenderingID != UIBackgroundTaskIdentifier.invalid {
        let app = UIApplication.shared
        app.endBackgroundTask(self.backgroundRenderingID)
        self.backgroundRenderingID = UIBackgroundTaskIdentifier.invalid
    }
    self.arView?.session.pause()
    self.arView?.session.delegate = nil
    self.arView?.scene.anchors.removeAll()
    self.arView?.removeFromSuperview()
    self.arView?.window?.resignKey()
    self.arView = nil
}

内存将增加到 90MB 到 250MB,一旦调用 deinit 它将减少到 175MB,不会清除所有内存。

同样在初始化的时候,我也设置了合适的选项

arView?.renderOptions = [
    .disableMotionBlur,
    .disableDepthOfField,
    .disablePersonOcclusion,
    .disableGroundingShadows,
    .disableFaceOcclusions,
    .disableHDR
]

但还是没有运气。

deinit之前:

deinit之后:

唉,RealityKit 2.0 / 1.0 开发人员无法从堆内存中释放 ARView,因为 Apple 有一个 poor-quality 实现。即使您在 SwiftUI 中将 arView 属性 声明为 weak,此实例也会立即 已释放,所以你不能使用它。然而,在 UIKit 中,将 arView 声明为 weak 没有任何效果。

如您所知,ARC 最初是在 Objective-C 中引入的,后来在 Swift 中实现的。 weakunowned 功能很可能由于某种原因没有为 ARView 实现,也许是因为 RealityKit 仅针对 Swift 量身定制 - @objc 属性明确说明了这一点。 ARC 似乎没有跟踪 ARView 引用。

@available(macOS 10.15, iOS 13.0, *)
@objc open class ARView : ARViewBase { ... }

如果您需要更多信息,请阅读this post了解详情。