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