【发布时间】:2016-06-11 18:12:10
【问题描述】:
我在这里没有想法,SceneKit 正在积累内存,而我才刚刚开始。我正在显示SNCNodes,它们存储在数组中,因此我可以分离分子的组件以进行动画处理。这些树模拟分子,我最终可能会展示 50 个,比如每个“章节”一个。问题是当我转到另一章时,前几章中的分子会保留在内存中。
分子节点是子节点的树。大约一半的节点是用于定向的空容器。否则,几何图形为SCNPrimitives(球体、胶囊和圆柱体)。每个几何体都有一个镜面反射和一个漫反射material,由一个UIColor 组成,不使用任何纹理。
当应用首次启动时,这些分子由代码构建并归档到字典中。然后,在随后的引导中,归档字典被读入本地字典以供 VC 使用。 (为简洁起见,我删除了这篇文章中的安全功能。)
moleculeDictionary = Molecules.readFile() as! [String: [SCNNode]]
当一章想要显示一个分子时,它会调用一个特定函数,该函数将给定分子所需的组件从本地字典加载到本地 SCNNode 属性中。
// node stores (reuseable)
var atomsNode_1 = SCNNode()
var atomsNode_2 = SCNNode()
. . .
func lysozyme() { // called by a chapter to display this molecule
. . .
components = moleculeDictionary["lysozyme"]
atomsNode_1 = components[0] // protein w/CPK color
baseNode.addChildNode(atomsNode_1)
atomsNode_2 = components[2] // NAG
baseNode.addChildNode(atomsNode_2)
. . .
}
在显示下一个分子之前,我调用了“清理”函数:
atomsNode_1.removeFromParentNode()
atomsNode_2.removeFromParentNode()
. . .
当我在仪器中进行调查时,大部分膨胀的内存是 C3DMeshCreateFromProfile 调用的 32 kB 块和 C3DMeshCreateCopyWithInterleavedSources 调用的 80 kB 块。
我也有需要追踪的泄漏,这些泄漏可追溯到存档的NSKeyedUnarchiver 解码。所以我也需要处理这些,但它们只是累积每个分子调用的内存使用的一小部分。
如果我返回到以前查看过的分子,内存使用量不会进一步增加,它会累积并持续存在。
我尝试将 atomsNode_1 及其亲属声明为可选项,然后在清理时将它们设置为 nil。没有帮助。我试过了,在清理功能中,
atomsNode_1.enumerateChildNodesUsingBlock({
node, stop in
node.removeFromParentNode()
})
嗯,内存恢复了,但节点现在似乎从加载的字典中永久消失了。该死的引用类型!
所以也许我需要一种方法来归档[SCNNode] 数组,以便单独取消归档和检索它们。在这种情况下,我会在完成后将它们从内存中清除,并在重新访问该分子时从存档中重新加载。但我还不知道如何做这些。在投入更多时间感到沮丧之前,我会很感激 cmets。
【问题讨论】: