SceneKit: too much memory is saved

Im from the ideas here, SceneKit imposes a memory and Im just starting. Im displaying SNCNodeswhich are stored in arrays, so I can separate the components of the molecule from the animation. These trees model molecules, of which I will ultimately have, perhaps, 50 to display, say, one per “chapter”. The problem is that when I move to another chapter, the molecules from the previous chapters are stored in memory.

Molecule nodes are trees of child nodes. About half of the nodes are empty containers for orientation. Otherwise, geometry SCNPrimitives(spheres, capsules and cylinders). Each geometry has a mirror and diffuse material, consisting of UIColornot used textures.

When the application first loads, these molecules are created from code and archived into a dictionary. Then, and at subsequent downloads, the archived dictionary is read into the local dictionary for use by VC. (Im shortening the security features in this post for brevity.)

moleculeDictionary = Molecules.readFile() as! [String: [SCNNode]]

When a chapter wants to map a molecule, it invokes a specific function that loads the necessary components for a given molecule from the local dictionary into local properties SCNNode.

// node stores (reuseable)
var atomsNode_1 = SCNNode() 
var atomsNode_2 = SCNNode()
        . . .

func lysozyme() {   // called by a chapter to display this molecule 
        . . .
    components = moleculeDictionary["lysozyme"]

    atomsNode_1 = components[0]         // protein w/CPK color
    baseNode.addChildNode(atomsNode_1)
    atomsNode_2 = components[2]         // NAG
    baseNode.addChildNode(atomsNode_2)
        . . .
 }

Before the next molecule is displayed, I call the "clear" function:

atomsNode_1.removeFromParentNode()
atomsNode_2.removeFromParentNode()
        . . .

When I research tools, most of the bloated memory is 32 kbytes of chunks called C3DMeshCreateFromProfileand 80 kB chunks C3DMeshCreateCopyWithInterleavedSources.

, , NSKeyedUnarchiver . , , .

, , .

Ive atomsNode_1 , . . Ive , ,

atomsNode_1.enumerateChildNodesUsingBlock({
    node, stop in
    node.removeFromParentNode()
})

, , , , . !

, , [SCNNode] , . , , . , . , , .

0
2

, . ? (segmentCount, radialSegmentCount ..). SCNPyramid ( ). , ( , , ). SCNBox ?

SCNLevelOfDetail, , . , , , , .

, , node. SCNNodes. . flattenedClone. . node , ; .

. - iOS, / . - Mac ( iOS?), node . SCNNode, " ".

swift "" (materials firstMaterial ?), node. , , , UIColor, , .

node . . . 0!

extension SCNNode {

public class func gizmoNode(axisLength: CGFloat) -> SCNNode {
    let offset = CGFloat(axisLength/2.0)
    let axisSide = CGFloat(0.1)
    let chamferRadius = CGFloat(axisSide)

    let xBox = SCNBox(width: axisLength, height: axisSide, length: axisSide, chamferRadius: chamferRadius)
    xBox.firstMaterial?.diffuse.contents = NSColor.redColor()
    let yBox = SCNBox(width: axisSide, height: axisLength, length: axisSide, chamferRadius: chamferRadius)
    yBox.firstMaterial?.diffuse.contents = NSColor.greenColor()
    let zBox = SCNBox(width: axisSide, height: axisSide, length: axisLength, chamferRadius: chamferRadius)
    zBox.firstMaterial?.diffuse.contents = NSColor.blueColor()
    let xNode = SCNNode(geometry: xBox)
    xNode.name = "X axis"
    let yNode = SCNNode(geometry: yBox)
    yNode.name = "Y axis"
    let zNode = SCNNode(geometry: zBox)
    zNode.name = "Z axis"

    let result = SCNNode()
    result.name = "Gizmo"
    result.addChildNode(xNode)
    result.addChildNode(yNode)
    result.addChildNode(zNode)
    xNode.position.x = offset
    yNode.position.y = offset
    zNode.position.z = offset

    let data = NSKeyedArchiver.archivedDataWithRootObject(result)
    let filename = "gizmo"

    // Save data to file
    let DocumentDirURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true)

    // made the extension "plist" so you can easily inspect it by opening in Finder. Could just as well be "scn" or "node"
    // ".scn" can be opened in the Xcode Scene Editor
    let fileURL = DocumentDirURL.URLByAppendingPathComponent(filename).URLByAppendingPathExtension("plist")
    print("FilePath:", fileURL.path)

    if (!data.writeToURL(fileURL, atomically: true)) {
        print("oops")
    }
    return result
}
}   
+2

SceneKit , , (C3DGenericSourceCreateDeserializedDataWithAccessors, C3DMeshSourceCreateMutable ..). , geometry nil SCNNode, Swift , .

, , - :

atomsNode_1.removeFromParentNode()
atomsNode_1.geometry = nil
atomsNode_2.removeFromParentNode()
atomsNode_2.geometry = nil

, :

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
    }
}

, , nil, .

+1

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


All Articles