我开发了一个应用程序,其中包括动态预览 3D 模型的分割结果的功能。我有自己的 catmull clark 分割函数来永久修改几何,但我使用 SCNGeometry 的 .subdivisionLevel 属性将模型临时分割为预览。在大多数情况下,预览并不意味着用户会选择永久选项。
.subdivisionLevel 使用(就像 MDLMesh 的分割一样,我尝试了它作为一种解决方法)皮克斯的 OpenSubdiv 来进行实际的分割和平滑。它的运行速度比我自己的要快,但更重要的是它不会永久修改我通过 SCNGeometry 源提供的顶点数据。
问题是,我无法让它停止泄漏内存。很久以前我第一次注意到这一点,认为这是我的代码中的东西。我不认为这只是一个特定的 IOS 版本,它发生在 Swift 和 Objective C 中。最终我设置了一个小例子,在 Xcode 中的 SceneKit 游戏模板中添加了 1 行,将船的 subdivisionLevel 设置为 1。 Instruments 显示立即导致内存泄漏:
我在一周前向 Apple 提交了一份错误报告,但我不确定我是否能很快得到答复或修复。屏幕截图来自一个非常小的模型的测试,但即使是小模型(几十到几千个顶点),它也会大量快速地泄漏并导致应用程序崩溃。
要重现,请在 Xcode 中基于 SceneKit 游戏模板创建一个新项目,并将以下行添加到 handletap:
if result.node.geometry!.subdivisionLevel == 3 {
result.node.geometry!.subdivisionLevel = 0
} else {
result.node.geometry!.subdivisionLevel = 3
}
(删除 ! 用于 objective-c )
点击船泄漏兆字节,再点击一下,它很快就会加起来。
OpenSubdiv 显然用于 3D Studio max 以及其他应用程序,而且它似乎在 Apple 的实现中。所以我的问题是:有没有办法在不完全放弃 SceneKit 的分割功能的情况下解决/避免这个问题,或者 Apple 的回应是我唯一的机会?
Best Answer-推荐答案 strong>
浏览 WWDC 视频以了解 Apple 对 OpenSubdiv 的 promise 程度以及他们修复漏洞的机会,我发现自从最新的 SceneKit 更新以来,Metal 可以在 GPU 上执行分割。
如果您想在 SceneKit 或模型 IO 中使用分割,这里是 必需的两行 (Swift):
let tess = SCNGeometryTessellator()
geometry.tessellator = tess
(来自 WWDC 2017 What's new in Scenekit,视频 23:45)
这将导致在 GPU 上执行分割(因此更快,尤其是在更高级别),使用更少的内存,最重要的是,在将分割级别设置为更低或回零时释放内存。
关于ios - 修复或避免默认第三方库中的内存泄漏,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/47296371/
|