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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With