SceneKit 在没有详细的崩溃信息的情况下崩溃

SceneKit crashes without verbose crash info

更新: 对于任何偶然发现这一点的人来说,SceneKit 似乎对它可以渲染的最大对象数有一个阈值。使用 [SCNNode flattenedClone] 是帮助增加它可以处理的对象数量的好方法。正如@Hal 所建议的,我将向 Apple 提交错误报告,描述下面讨论的性能问题。

我对 iOS 有点陌生,我目前正在为 class 开发我的第一个 OS X 项目。我本质上是在创建随机几何图形(space 中的随机点如果它们之间的距离≤给定半径则相互连接)并且我正在使用 SceneKit 来显示结果。我已经知道我正在将 SceneKit 推向极限,但是如果我试图绘制的对象数量太多,整个过程就会崩溃,我不知道如何解释结果。

我的 SceneKit 场景由默认相机、2 个照明节点组成,每个节点在 SCNNode(图中的节点)内大约 5,000 SCNSpheres,然后是大约 50,0000 个连接属于 SCNPrimitiveSCNGeometryPrimitiveTypeLine 类型,也在 SCNNode 之内。然后将所有这些节点添加到一个大节点,并将其添加到我的场景中。

该代码适用于较少数量的球体和连接。

当我 运行 我的应用程序符合这些规范时,一切似乎都运行良好,然后在执行以下行后 5-10 秒:

dispatch_async(dispatch_get_main_queue(), ^{ [self.graphSceneView.scene.rootNode addChildNode:graphNodes]; });

应用程序崩溃并显示此结果屏幕:

考虑到我是 Xcode 的新手并且习惯了崩溃时更详细的输出,我有点不知所措。我该怎么做才能获得有关此崩溃的更多信息?

这肯定是简洁的输出。你可以通过简化来攻击它,直到你不再看到崩溃。

首先,您在屏幕上看到过什么吗?

其次,您来电

dispatch_async(dispatch_get_main_queue(), ^{
    [self.graphSceneView.scene.rootNode addChildNode:graphNodes];
});

仍然在主队列上运行,所以我希望它不会对感知速度或响应能力产生影响。因此,将 addChildNode: 从 GCD 块中取出并直接调用它。这有什么区别吗?至少,您会立即看到崩溃,并可能获得更好的堆栈跟踪。

第三,从像 SCNPrimitiveSCNGeometryPrimitiveTypeLine 这样的基元创建自己的几何体比使用 SCNGeometry 子类更棘手。该步骤中的内存管理不善可能会引发神秘的崩溃。如果移除这些连接线会发生什么?如果将它们替换为又长又瘦的 SCNBox 实例会怎样?您最终可能会选择使用 SCNBox,因为在 SceneKit 中设置样式比原始线条更容易。

第四,看看@rickster对这个关于优化的问题的回答:SceneKit on OS X with thousands of objects。听起来您的项目会受益于节点扁平化 (flattenedClone),并且可能会受益于 SCNLevelOfDetail。但是这些建议属于过早优化的范畴,万恶之源。

听听在 Metal 和 OpenGL 渲染器之间切换会产生什么结果会很有趣。这是 IB 中 SCNView 的设置(我认为是 "preferred renderer"),以及 Info.plist 中的可选条目。