将12 ARFrame添加到阵列(iOS / Swift)后,ARSCNView冻结

时间:2018-07-18 03:02:47

标签: ios iphone swift scenekit arkit

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

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

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

self.ARFrames.append(frame)

奇怪的是,func session(_ session: ARSession, didFailWithError error: Error)在此过程中没有调用,也未报告任何其他错误,该应用程序不会崩溃,并且其他所有用户控件均正常运行,只有ARSCNView被冻结并didpUdate事件将不会被调用。与ARSCNView freezes when adding 14 ARAnchor subclass objects with strong reference类似,但是那里的页面没有解决方案。同样,在应用程序进入后台并返回后,即使之前冻结了场景视图,也将调用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
        }
    }
}

1 个答案:

答案 0 :(得分:1)

每个ARFrame都包含一个直接来自摄像机捕获系统的视频帧(位于其capturedImage属性中)。

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

  

如果多个样本缓冲区引用此类内存池的时间过长,则输入将不再能够将新样本复制到内存中,并且这些样本将被丢弃。

     

如果您的应用程序由于将提供的CMSampleBuffer对象保留太长时间而导致删除样本,但是它需要长时间访问样本数据,请考虑将数据复制到新的缓冲区中,然后释放样本缓冲区(如果以前已保留),以便可以重用其引用的内存。

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

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