scene kit memory management using swift
So I found out what I needed to do was set the texture on my game objects to nil before removing them from the parent. Just as a general rule, I started setting all my textures to nil before deleting the node. Anyway, this solved my memory problem.
Managing memory in Swift (SceneKit game)
I also meet the same case.And I find a solution to fix the bug.You must asynchronous to remove and release scnView.Just look the following code.
_scnView.antialiasingMode = SCNAntialiasingModeNone;
__block SCNView *strongScnView = _scnView;
_scnView = nil;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[strongScnView setScene:nil];
[strongScnView removeFromSuperview];
[strongScnView stop:nil];
strongScnView = nil;
});
SceneKit: too much memory persisting
Spheres, capsules, and cylinders all have fairly dense meshes. Do you need all that detail? Try reducing the various segment count properties (segmentCount
, radialSegmentCount
, etc). As a quick test, substitute SCNPyramid
for all of your primitive types (that's the primitive with the lowest vector count). You should see a dramatic reduction in memory use if this is a factor (it will look ugly, but will give you immediate feedback on whether you're on a usable track). Can you use a long SCNBox
instead of a cylinder?
Another optimization step would be to use SCNLevelOfDetail
to allow substitute, low vertex count geometry when an object is far away. That would be more work than simply reducing the segment counts uniformly, but would pay off if you sometimes need greater detail.
Instead of managing the components yourself in arrays, use the node hierarchy to do that. Create each molecule, or animatable piece of a molecule, as a tree of SCNNodes
. Give it a name. Make a flattenedClone
. Now archive that. Read the node tree from archive when you need it; don't worry about arrays of nodes.
Consider writing two programs. One is your iOS program that manipulates/displays the molecules. The other is a Mac (or iOS?) program that generates your molecule node trees and archives them. That will give you a bunch of SCNNode tree archives that you can embed, as resources, in your display program, with no on-the-fly generation.
An answer to scene kit memory management using swift notes the need to nil out "textures" (materials
or firstMaterial
properties?) to release the node. Seems worth a look, although since you're just using UIColor I doubt it's a factor.
Here's an example of creating a compound node and archiving it. In real code you'd separate the archiving from the creation. Note also the use of a long skinny box to simulate a line. Try a chamfer radius of 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
}
}
SpriteKit Memory increase every time new scene presented
I tried checking if things had not been deallocated and this did not solve the problem. I used a developer technical support ticket and an engineer advised me to turn off "GPU Frame Capture" in the scheme for the project.
This 95% solved the problem. Memory usage has reduced to a lot more reasonable amount and the app no longer continues to build up memory usage after I implement reasonable methods to deallocate scenes, nodes etc...
I asked if this solution was only for testing in Xcode and I was told it was not, this is how my app will perform on the App Store:
"GPU Frame Capture is a tool for debugging and is only present when running your app with the Xcode Debugger attached!" - Said the engineer.
SpriteKit retaining memory after I leave game
Based on your comments, you should use capture lists:
func createHerosAction(duration: Double = 5.0){
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run {[unowned self] in
self.addHero()
},
SKAction.wait(forDuration: duration)
])
), withKey:"createHeros")
}
It is a big topic, but I suggest you to start reading the link I have posted, because it has everything explained in detail starting from "How ARC works", "What are Capture Lists" to the weak and unowned keywords. I wrote few times about this already, as well as many others on this site, and it is a big topic, so I will skip that this time :)
Related Topics
Swift Good Coding Practice: If Statement with Optional Type Bool
Target Is Not Found, Please Reconnect the Device, Xcode:Device Support File
Unrecognized Selector Sent to Instance Swift 3
Firebase Authentication Error in Other Languages
Screen Recording When My iOS App Is in Background with Replaykit
How to Load Thousands Records to Realm Correctly
Avplayerlayer Shows Black Screen But Sound Is Working
Swift Computed Properties Cannot Be Used in Init
Countdown with Several Decimal Slots, Using Nstimer in Swift
Didoutputsamplebuffer Delegate Not Called
Swift iOS Record Video and Audio with Avfoundation
Using Avaudioplayer to Play Remote Mp3 File in Swift
Swift Bridging Header File Won't Work with Use_Frameworks
Ios: How to Create Expandable Tableview in Swift Without Using Third Party Libraries or Pods
Save Struct in Class to Nsuserdefaults Using Swift
How to Make App Wait Until Firebase Request Is Finished
How to Make Designable Textfield Code Class in Swift
Adding a Target to a Button Programmatically Throws an Error "Unrecognized Selector Sent to Class"