【问题标题】:SceneKit crashes without verbose crash infoSceneKit 在没有详细崩溃信息的情况下崩溃
【发布时间】:2016-03-19 08:33:08
【问题描述】:

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

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

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

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

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

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

应用程序崩溃并出现以下结果屏幕:

考虑到我是 Xcode 的新手,并且习惯了在崩溃时更详细的输出,我有点不知所措。如何获取有关此崩溃的更多信息?

【问题讨论】:

    标签: objective-c macos scenekit


    【解决方案1】:

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

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

    第二,你的电话

    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 的设置(我认为是“首选渲染器”),以及 Info.plist 中的可选条目。

    【讨论】:

    • 感谢您的详细回复!好的,所以 (1) 首先,你有没有在屏幕上看到任何东西? 是的!该应用程序适用于较少数量的节点和边。如果我以 10 的度数(50,000 个 SCNNodes)做 5,000,它工作正常。 (2) 关于主队列,将该调用移至块外的addChildNode 似乎没有任何影响;我这样做是因为我一直被教导将影响 UI 的东西放在主队列中。我会按照你的建议删除它。 (3) _ 如果你移除那些连接线会发生什么?_ 我可以处理更多的 SCNNodes...
    • [续] 我没有使用另一个 SCNGeometry 子类的原因是它似乎具有相同的效果,但它可以处理的阈值要低得多。我使用了圆柱体,但 SceneKit 无法处理那么多物体。使圆柱体的位置和旋转正确也非常困难,但我保存了该代码,以便如果这看起来是一条更好的路线,我可以切换回去。最后,我会确保查看该链接,这听起来是一个很棒的资源。再次感谢您的帮助,如果我的回复有帮助,请告诉我!
    • 听起来你已经达到了极限,而且你的实现代码是正确的。我建议 SCNBox/SCNCylinder 只是为了排除新手错误——所以不要考虑这个想法。我认为在将其添加到场景之前,您最好的选择是您的图表的flattenedClone。请务必在 bugreport.apple.com 上为您的项目提交性能报告。
    • 所以flattenedClone听起来正是我需要的。用了之后,居然报了一个详细的错误,原来是这样,哈哈,结果如下:SceneKit: error, RendererElementStore does not support span of more than 65536
    • 也许将您的连接线分成多个节点?我从来没有见过那个错误。您肯定应该针对文档提交错误报告。
    猜你喜欢
    • 2020-01-09
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-13
    相关资源
    最近更新 更多