向数组添加 12 个 ARFrame 后 ARSCNView 冻结 (iOS/Swift)

ARSCNView freezes after adding 12 ARFrame to Array (iOS/Swift)

我在 ViewController.swift 中有一个 ARSCNView,我想将 ARFrames 保存到

中的预分配数组
func session(_ session: ARSession, didUpdate frame: ARFrame)

但是,在处理大约 11-13 ARFrames 之后,整个 ARSCNView 将通过使用

冻结
self.ARFrames.append(frame)

奇怪的是 func session(_ session: ARSession, didFailWithError error: Error) 在此过程中没有调用,也没有报告任何其他错误,应用程序没有崩溃,其他所有用户控件都工作正常,只有 ARSCNView freeze 和 dippUdate 事件不会被调用。类似于 ARSCNView freezes when adding 14 ARAnchor subclass objects with strong reference 但那里的页面没有解决方案。此外,在应用程序进入后台并 returns 返回后,调用 sessionWasInterrupted(:)sessionInterruptionEnded(:),即使场景视图之前已冻结。 这是 iOS 11 的错误吗?

这是我在我的应用中使用的完整代码。

import UIKit

class ViewController: UIViewController,ARSCNViewDelegate,ARSessionDelegate {
    @IBOutlet var sceneView: ARSCNView!
    let configuration = ARFaceTrackingConfiguration()
    var ARFrames = [ARFrame]()
    var imgCount = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        ARFrames.reserveCapacity(300)
        sceneView.delegate = self
        sceneView.session.delegate = self
        sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    }

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        if (frame.capturedDepthData == nil || self.imgCount >= 300){
            return
        }
        DispatchQueue.global().async {
            self.ARFrames.append(frame)
            self.imgCount += 1
        }
    }
}

每个 ARFrame 包含一个直接来自相机捕获系统的视频帧(在其 capturedImage 属性 中)。

捕获系统提供的每一帧都来自一个固定大小的内存池,捕获系统会在会话继续时重复使用该内存池。如捕获中所述 docs:

If multiple sample buffers reference such pools of memory for too long, inputs will no longer be able to copy new samples into memory and those samples will be dropped.

If your application is causing samples to be dropped by retaining the provided CMSampleBuffer objects for too long, but it needs access to the sample data for a long period of time, consider copying the data into a new buffer and then releasing the sample buffer (if it was previously retained) so that the memory it references can be reused.

通过将您获得的所有 ARFrame 添加到数组中,您声称拥有(即保留)它们的像素缓冲区,并最终使内存捕获系统无法写入新帧。和 ARKit需要连续的视频流,因此您的 AR 会话放弃了。

解决办法?不要抓住所有这些框架。仅将每一帧中您需要的任何信息复制到您自己的数据结构中。