Spencer
Spencer

Reputation: 382

SceneKit crashes without verbose crash info

Update: For anyone who stumbles upon this, it seems like SceneKit has a threshold for the maximum number of objects it can render. Using [SCNNode flattenedClone] is a great way to help increase the amount of objects it can handle. As @Hal suggested, I'll file a bug report with Apple describing the performance issues discussed below.

I'm somewhat new to iOS and I'm currently working on my first OS X project for a class. I'm essentially creating random geometric graphs (random points in space connected to one another if the distance between them is ≤ a given radius) and I'm using SceneKit to display the results. I already know I'm pushing SceneKit to its limits, but if the number of objects I'm trying to graph is too large, the whole thing just crashes and I don't know how to interpret the results.

My SceneKit scene consists of the default camera, 2 lighting nodes, approximately 5,000 SCNSpheres each within an SCNNode (the nodes on the graph), and then about 50,0000 connections which are of type SCNPrimitiveSCNGeometryPrimitiveTypeLine which are also within SCNNodes. All of these nodes are then added to one large node which is added to my scene.

The code works for smaller numbers of spheres and connections.

When I run my app with these specifications, everything seems to work fine, then 5-10 seconds after executing the following lines:

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

the app crashes with this resulting screen: this resulting screen.

Given that I'm sort of new to Xcode and used to more verbose output upon crashing, I'm a bit over my head. What can I do to get more information on this crash?

Upvotes: 2

Views: 1050

Answers (1)

Hal Mueller
Hal Mueller

Reputation: 7655

That's terse output for sure. You can attack it by simplifying until you don't see the crash anymore.

First, do you ever see anything on screen?

Second, your call to

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

still runs on the main queue, so I would expect it to make no difference in perceived speed or responsiveness. So take addChildNode: out of the GCD block and invoke it directly. Does that make a difference? At the least, you'll see your crash immediately, and might get a better stack trace.

Third, creating your own geometry from primitives like SCNPrimitiveSCNGeometryPrimitiveTypeLine is trickier than using the SCNGeometry subclasses. Memory mismanagement in that step could trigger mysterious crashes. What happens if you remove those connection lines? What happens if you replace them with long, skinny SCNBox instances? You might end up using SCNBox by choice because it's easier to style in SceneKit than a primitive line.

Fourth, take a look at @rickster's answer to this question about optimization: SceneKit on OS X with thousands of objects. It sounds like your project would benefit from node flattening (flattenedClone), and possibly the use of SCNLevelOfDetail. But these suggestions fall into the category of premature optimization, the root of all evil.

It would be interesting to hear what results from toggling between the Metal and OpenGL renderers. That's a setting on the SCNView in IB ("preferred renderer" I think), and an optional entry in Info.plist.

Upvotes: 1

Related Questions