SceneKit leaks when cloning a node

I have asset loading and caching, defined as such:

class AssetLoader { fileprivate var rootNodes = Dictionary<String, SCNNode>() static let sharedInstance = AssetLoader() fileprivate init() { } func rootNode(_ named: String) -> SCNNode { if self.rootNodes[named] != nil { return self.rootNodes[named]!.clone() } else { let scene = SCNScene(named: "art.scnassets/\(named).scn") self.rootNodes[named] = scene!.rootNode return self.rootNodes[named]!.clone() } } } 

I use it to make the scene faster. I create assets from extensions as such:

 extension CAAnimation { class func animationWithScene(named: String) -> CAAnimation? { unowned let rootNode = AssetLoader.sharedInstance.rootNode(named) var animation: CAAnimation? rootNode.enumerateChildNodes({ (child, stop) in if child.animationKeys.count > 0 { animation = child.animation(forKey: child.animationKeys.first!) stop.initialize(to: true) } }) return animation } } extension SCNNode { class func nodeWithScene(named: String) -> SCNNode? { unowned let rootNode = AssetLoader.sharedInstance.rootNode(named) let node = SCNNode() for child in rootNode.childNodes { node.addChildNode(child) } node.eulerAngles = SCNVector3(x: Float(-M_PI_2), y: 0, z: 0) node.scale = SCNVector3Make(kMeshScale, kMeshScale, kMeshScale) return node } } 

The tools say that I console memory like crazy with every call to clone (). I tried to use the weak and not having the right, wherever I was, without the occurrence of failures, and this does not change anything. Somebody knows? Is this a bug in SceneKit?

thanks

+5
source share
1 answer

If I understand correctly, you save your source nodes in the rootNodes dictionary of your AssetLoader and return a clone from the rootNode function.

My architecture is similar, and my problem was this: when I remove the cloned node from the scene tree, the memory will not be released. It's your problem?

I fixed the problem by adding the β€œupload” function to my singleton to reset the original nodes when deleting the cloned nodes from the scene tree. This fixed memory problems.

With code that would look something like this:

 func unloadRootNode(_ named: String) { rootNodes.removeValue(forKey: named) } 
+2
source

Source: https://habr.com/ru/post/1264963/


All Articles