5

I am building an app that uses Scenekit to display a scene based on information returned from a data base. I have created a custom class with a class func that creates a SCNNode containing everything that needs to be drawn and returns it to my SCNView. Before calling this function I remove any existing nodes. Everything works great until I need to call it a second time. After removing the old SCNNode The memory is not deallocated before creating the new one. Is there a standard way of removing and replacing an SCNNode without overloading memory? I'm new to iOS dev and have never really done graphics before either. Thanks

PaulB
  • 111
  • 2
  • 13
  • How did you diagnose that memory is not being deallocated? – rickster Oct 07 '15 at 18:05
  • My app was crashing immediately after receiving memory warnings so I checked in debugger and also instruments >> allocations. The memory usage went up when loading the scene and reduced if I cleared the screen but only if a new scene was not loaded afterwards. Does that make sense? I think ARC is holding the SCNNode because I'm redrawing the scene. – PaulB Oct 08 '15 at 19:11
  • Hey Paul, ever work this out? I'm currently having the same issue. http://stackoverflow.com/questions/35687122/scenekit-too-much-memory-persisting – bpedit Feb 29 '16 at 04:30
  • 1
    @bpedit Yes, I found somewhere that if you explicitly assign the geometry node a value of nil then it fully deallocates. So after removing all the child nodes from your scene node add a line something like this, self.geometryNode = nil – PaulB Feb 29 '16 at 04:43
  • I suppose I have to do this with enumeration on all the children with geometry also? Thanks, Byrne. – bpedit Feb 29 '16 at 04:58
  • Yes, if you have multiple geometries. If all the shapes are drawn and erased at the same times then you can put them all in one node to make your code shorter and faster, that's what I did – PaulB Feb 29 '16 at 05:03
  • Let me know if that works for you. I did this several months ago and might be forgetting parts of it – PaulB Feb 29 '16 at 05:05

1 Answers1

11

I had the same problem, with my SceneKit app leaking a lot of memory. The memory of the SCNNode is freed if you set its geometry property to nil before letting Swift deinitialize it.

Here is an example of how you may implement it:

class ViewController: UIViewController {
    @IBOutlet weak var sceneView: SCNView!
    var scene: SCNScene!

    // ...

    override func viewDidLoad() {
        super.viewDidLoad()
        scene = SCNScene()
        sceneView.scene = scene

        // ...
    }

    deinit {
        scene.rootNode.cleanup()
    }

    // ...
}

extension SCNNode {
    func cleanup() {
        for child in childNodes {
            child.cleanup()
        }
        geometry = nil
    }
}
Daniel Jonsson
  • 3,261
  • 5
  • 45
  • 66