我在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
}
}
}
答案 0 :(得分:1)
每个ARFrame
都包含一个直接来自摄像机捕获系统的视频帧(位于其capturedImage
属性中)。
捕获系统售出的每个帧都来自固定大小的内存池,捕获系统会在会话继续时重用该内存池。如捕获docs中所述:
如果多个样本缓冲区引用此类内存池的时间过长,则输入将不再能够将新样本复制到内存中,并且这些样本将被丢弃。
如果您的应用程序由于将提供的CMSampleBuffer对象保留太长时间而导致删除样本,但是它需要长时间访问样本数据,请考虑将数据复制到新的缓冲区中,然后释放样本缓冲区(如果以前已保留),以便可以重用其引用的内存。
通过将所有获得的ARFrame
添加到数组中,您声明拥有(即保留)其像素缓冲区的所有权,并最终使捕获系统的内存不足而无法写入新帧。ARKit需要一个连续的视频流,因此您的AR会话放弃了。
解决方案?不要抓住所有这些框架。仅将每个框架中需要的任何信息复制到自己的数据结构中。