I am building an iOS game aimed for the new iOS 7 and Sprite Kit, using emitter nodes and physics to enhance gameplay. While developing the app, I ran into a serious problem: you create your scenes, nodes, effects, but when you are done and need to return to the main screen, how do you free up all the memory allocated by these resources?
Ideally ARC should free up everything and the application should get back to the memory consumption level it had before creating the scene, but this is not what happens.
I've added the following code, as the dealloc method of the view, which draws the scene and is responsible for removing everything upon getting closed (removed):
- (void) dealloc
{
if (scene != nil)
{
[scene setPaused:YES];
[scene removeAllActions];
[scene removeAllChildren];
scene = nil;
[((SKView *)sceneView) presentScene:nil];
sceneView = nil;
}
}
I would very much appreciate any help on this matter.
What is SpriteKit? SpriteKit is a powerful 2D sprite-based framework for games development from Apple. SpriteKit uses SKView which is a scene, it is the visual that you see on your screen. For those who are familiar with making iOS App, it is similar to Storyboard.
The SpriteKit framework makes it easy to create high-performance, battery-efficient 2D games. With support for custom OpenGL ES shaders and lighting, integration with SceneKit, and advanced new physics effects and animations, you can add force fields, detect collisions, and generate new lighting effects in your games.
SpriteKit is a general-purpose framework for drawing shapes, particles, text, images, and video in two dimensions. It leverages Metal to achieve high-performance rendering, while offering a simple programming interface to make it easy to create games and other graphics-intensive apps.
I had a lot of memory problems with Sprite Kit, and I used a tech support ticket to get info, and it may relate here. I was asking whether starting a new SKScene would totally release all the memory the previous one used. I found out this:
The underlying memory allocated by +textureWithImageNamed: may or may not (typically not) be released when switching to new SKScene. You cannot rely on that. iOS releases the memory cached by +textureWithImageNamed: or +imageNamed: when it sees fit, for instance when it detects a low-memory condition.
If you want the memory released as soon as you’re done with the textures, you must avoid using +textureWithImageNamed:/+imageNamed:. An alternative to create SKTextures is to: first create UIImages with +imageWithContentsOfFile:, and then create SKTextures from the resulting UIImage objects by calling SKTexture/+textureWithImage:(UIImage*).
I don't know if this helps here.
All of that code is superfluous. Provided that you have no memory leaks or retain cycles in your code, once you release the Sprite Kit view everything will be cleared from memory.
Under the hood Sprite Kit employs a caching mechanism but we have no way of controlling it, nor should we need to if it is properly implemented (which is safe to assume).
If this is not what you're seeing in Instruments, check for retain cycles, leaks. Verify that dealloc of the scene and view does get called. Make sure no strong references to view, scene or other nodes remain in other objects (particularly singletons and global variables).
After fighting this for a couple days, the key was in fact: [sceneView presentScene:nil]; Or for Swift: sceneView.presentScene(nil)
which can be done in viewDidDisappear. Without this, your view will hang on to the scene for dear life, even after being dismissed, and continue to chew memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With