4

I'm adding nodes to the scene and removing them once they leave the camera's field of view like this:

func removeUnusedBlocks() {
    for child in mapNode.childNodes {
            if !sceneView.isNode(child, insideFrustumOf: cameraNode) && 
  child.worldPosition.z > playerNode.worldPosition.z {
                child.removeFromParentNode()
                blocks.removeFirst()
            }
     }
}

removeUnusedBlocks() is being called successfully from func renderer(_ renderer: SCNSceneRenderer, didApplyAnimationsAtTime time: TimeInterval) { } so I know the nodes are being removed from the scene.

However, the memory persists and increases! I see the fps decreasing rapidly, and Delegate (pink section) increasing.

enter image description here

I looked at the answers here about setting the geometry to nil and added this in the GameViewController.swift:

deinit {
  scene.rootNode.cleanup()
}

And after GameViewController.swift closing braces:

extension SCNNode {
    func cleanup() {
        for child in childNodes {
            child.geometry = nil
        }
    }
}

But it hasn't done anything. What can I do?

sinio
  • 701
  • 1
  • 9
  • 18
  • "I looked at the answers here" Where is 'here'? "added this in" Add it where? – El Tomato Jan 29 '18 at 02:56
  • @ElTomato edited my answer to include those details – sinio Jan 29 '18 at 05:38
  • how is `mapNode` managed? If nodes are never removed from it then memory will always grow, and iterating over more and more nodes will lead to more time spent in the delegate method. – mnuages Jan 29 '18 at 16:09
  • @mnuages The block nodes that contain all other nodes are added to `mapNode`. When these blocks go out of the screen (it's a sidescrolling game), they're removed from `mapNode` via `removeUnusedBlocks()` I added in my question. Ha, strange. I just commented out `removeUnusedBlocks()` and it's running great now. This is weird considering the nodes are now not being removed but it's running better :/ – sinio Jan 29 '18 at 16:15
  • also note that in Cocoa it's not safe to remove an item from a collection while iterating on this collection. – mnuages Jan 29 '18 at 16:19
  • I thought `child.removeFromParentNode()` removed the node. – sinio Jan 29 '18 at 16:21
  • update: no, removing `removeUnusedBlocks()` didn't fix things. It just ran well for longer than before, but it still eventually slows. – sinio Jan 29 '18 at 16:57
  • @sinio Setting the geometry to nil has stopped working for me and my app is leaking memory again. Did you find a solution to your problem? – Daniel Jonsson Dec 26 '18 at 22:53
  • I'm curious about what the pink Delegate section actually is. I think if we understood that better it would offer insight to these problems of memory and nodes and high delegate times being related. The Delegate section is starting to get large in my own app and would like to see it lower. Unfortunately there isn't much documentation from Apple on the statistics chart. @mnuages Can you offer any more info on what the Delegate section is telling us and what "method" are you referring to, thanks. – The Way Feb 03 '19 at 04:20
  • Hey guys, I know this is an old question, but: I've been having memory problems with my own SceneKit project and I've discovered that there's a difference between setting the geometry to nil `someNode.geometry = nil` and explicitly emptying the materials array BEFORE clearing the geometry, like this: `someNode.geometry?.materials = []`. This had a huge impact on my memory situation, as determined by `Instruments`. I don't know if this is specific to my project or not, but it's worth a try! – West1 Dec 01 '22 at 21:47

0 Answers0