Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing SCNNode nodes from scene.rootNode is causing a crash, in SceneKit

I am trying to remove set of nodes from my scene which represent a path. They are a combination of SCNSphere geometry nodes, and custom geometry representing lines, created using SCNGeometrySource and SCNGeometryElement.

I am not retaining these nodes in any kind of array. Instead, I search the first level of the node tree of the rootNode in the scene for these nodes, by their name, and the subsequent call an action sequence that makes them fade out, and they should remove themselves from the root node.

The code is as follows:

func clearPath() {
    //
    let disappear = SCNAction.fadeOut(duration: 0.1)
    let remove = SCNAction.removeFromParentNode()
    let sequence = SCNAction.sequence([disappear, remove])

    if let pathNodesToRemove = pathNodes() {
        //
        for node in pathNodesToRemove {
            //
            node.removeAllActions()
            node.runAction(sequence)
        }
    }

    if let lineNodesToRemove = lineNodes() {
        for node in lineNodesToRemove {
            //
            node.removeAllActions()
            node.runAction(sequence)
        }
    }

    path.removeAll()
}

where:

func pathNodes() -> [SCNNode]? {
    //

...        

    let nodes = rootNode.childNodes.filter { (node) -> Bool in
        //
        guard let name = node.name else { return false }
        if name.hasPrefix(configurationComponent.id) &&
            name.range(of:"_PATH") != nil {
            return true
        } else {
            return false
        }
    }

    return nodes
}

The lineNodes() function is basically the same.

I switched on Zombie Objects to trace where the error is coming from, and I always get the same error: a reference to SceneKit`C3DNodeRemoveFromParentNode as the last thing to call on the thread, and a EXC_BAD_ACCESS (code=1, address... ).

The clearPath() function is the only place in the entire app that I am calling 'RemoveFromParentNode'.

The nodes don't have physics bodies on them and are not being retained anywhere elsewhere.

Any thoughts as to how to resolve this?

EDIT 28/4/18:

Here is a crash report of the thread where it occurs. It would appear that removeObjectFromChildNodesAtIndex is being called twice...

    Thread 9 name:  Dispatch queue: com.apple.scenekit.renderingQueue.Air_Relay.ARTCSCNView0x104126720
Thread 9 Crashed:
0   SceneKit                        0x00000001957d668c C3DNodeRemoveFromParentNode + 40
1   SceneKit                        0x0000000195826e28 -[SCNNode __removeObjectFromChildNodesAtIndex:] + 184
2   SceneKit                        0x0000000195826e28 -[SCNNode __removeObjectFromChildNodesAtIndex:] + 184
3   SceneKit                        0x0000000195827350 -[SCNNode removeFromParentNode] + 396
4   SceneKit                        0x000000019593e9fc -[SCNActionRemove updateWithTarget:forTime:] + 92
5   SceneKit                        0x0000000195907cb8 SCNCActionSequence::cpp_updateWithTargetForTime+ 2202808 (SCNNode*, double) + 316
6   SceneKit                        0x00000001957bcfb0 SCNActionApply + 112
7   SceneKit                        0x0000000195853d2c _applyActions + 236
8   CoreFoundation                  0x00000001814dccbc __CFDictionaryApplyFunction_block_invoke + 24
9   CoreFoundation                  0x00000001814c3f98 CFBasicHashApply + 132
10  CoreFoundation                  0x00000001814cdb64 CFDictionaryApplyFunction + 288
11  SceneKit                        0x0000000195853b5c C3DAnimationManagerApplyActions + 92
12  SceneKit                        0x000000019583b054 -[SCNRenderer _update:] + 656
13  SceneKit                        0x000000019583d018 -[SCNRenderer _drawSceneWithNewRenderer:] + 252
14  SceneKit                        0x000000019583d69c -[SCNRenderer _drawScene:] + 84
15  SceneKit                        0x000000019583daa0 -[SCNRenderer _drawAtTime:] + 728
16  SceneKit                        0x00000001958e446c -[SCNView _drawAtTime:] + 512

EDIT 30/04/18

I continued to add other features to the app, where I needed to remove nodes using SCNAction.removeFromParentNode(). I isolated those as well to cause the problem independently of the above code.

These are called more frequently on the SCNRendererDelegate update as each new nodes are generated.

I also tried to use removeFromParentNode() directly on the node using SCNAction.run block, and the same issue occurs.

like image 281
nightbird Avatar asked Apr 26 '18 21:04

nightbird


1 Answers

When you use SCNAction.removeFromParentNode() you aren't removing the node, you have to remove the node it's self. If you remove the path or action you are essentially make a value nil so when the path or action is called there is now a nil value and it crashes.

like image 129
Lucas Dahl Avatar answered Nov 14 '22 14:11

Lucas Dahl