I have a lot of characters in my game and because of that I have so many textures. When a texture atlas is loaded (containing about 5 different image textures) it increases the memory use and keeps it there at that amount. So the more textures just keeps driving that number up and up until sometimes the application crashes. I don't need all the characters at once, how can i maybe load some character textures when I need them and deallocate the others when i don't, but ill need to be able to bring it back.

- 58,465
- 13
- 121
- 148

- 391
- 1
- 7
- 28
-
I'm not sure the problem really here is having too many texture in memory. Can you tell us how many texture (and related KB) are we talking about? – Luca Angeletti Jun 15 '16 at 22:08
-
Yes so I have 21 different texture atlases, bringing a total of 105 different textures in memory. When i preload all of them at once before the game starts, my memory use shoots up to 555 mb(56.1%), I also get a "Received memory warning" in my debugger console. @appzYourLife – OriginalAlchemist Jun 15 '16 at 22:15
-
Can you arrange your textures so that all the textures needed for a given scene are inside a few number of texture atlas? – Luca Angeletti Jun 15 '16 at 22:16
-
So all the textures are needed inside of the same scene, but they aren't needed at the same time. This is how it works, the different textures are different characters, I have a collection view with all the characters at the bottom of the scene and they can select who they want to play with, selecting a different character simply changes the nodes textures. They obviously can't play with them all at the same time so i was thinking of somehow deallocating all the texture atlases of the characters that aren't selected and only loading the one that is. – OriginalAlchemist Jun 15 '16 at 22:21
-
You might want to have a look at this SO answer on the topic of reducing memory use caused by loading lots of textures: http://stackoverflow.com/a/38679128/763355 – MoDJ Jul 31 '16 at 22:21
1 Answers
Rule 1
First of all you don't need to manually load in memory your texture atlas. When you create a sprite with this code
let sprite = SKSpriteNode(imageNamed: "Dog")
SpriteKit looks for an image named Dog
and if it cannot find it then it automatically looks for the image inside all your texture atlases.
When the image is found inside a texture atlas the whole texture atlas is automatically loaded in memory.
This is why you can avoid manually loading the texture atlas.
Rule 2
Don't bother about removing the texture atlas from memory
When you stop using all the images inside a given texture atlas it is automatically removed from memory. This could not happen immediately if the system has "enough" memory but it will happen eventually.
This is why you don't need to manually remove a texture atlas from memory
What can you do?
You should group your textures into several texture atlases following the logic of your game.
If you have 30 textures and you know that only the 1...10 OR 11...20 OR 21...30 will be used at the same time then create 3 texture atlases like follow:
- TextureAtlas1: images from 1 to 10
- TextureAtlas2: images from 11 to 20
- TextureAtlas3: images from 21 to 30
This will make the SpriteKit work more effective.

- 58,465
- 13
- 121
- 148
-
Thank you! Very great descriptive answer! Ah okay, so just having the textures is fine, but could the crashing occur because I'm trying to load too many textures at one time? Thus I should load them in pieces when they are needed? – OriginalAlchemist Jun 15 '16 at 22:43
-
@OriginalAlchemist: __Yes__, for now I really suggest you to avoid preloading all the textures. Just load a texture when you really need it and leave the optimizations to SpriteKit. – Luca Angeletti Jun 15 '16 at 22:45
-
-
Where are you getting these rules from? by Rule 2 logic, when you preload an atlas, it will automatically deinit because you haven't specified sprites yet – Knight0fDragon Jun 16 '16 at 14:39
-
@Knight0fDragon: right but I was afraid the OP was manually retaining the texture atlas somewhere. – Luca Angeletti Jun 16 '16 at 14:41
-
Also swift/objc does not use garbage collection, so it does not remove things based on available memory, it removes it once no more references are available to it – Knight0fDragon Jun 16 '16 at 14:44
-
@Knight0fDragon: things are little bit different with TextureAtlas. There is a caching system in SpriteKit. If the system has lots of memory available SpriteKit can decide to keep the Texture Atlas in memory even no longer referenced. Look [here](http://stackoverflow.com/questions/20889211/does-sprite-kit-load-a-texture-atlas-multiple-times-if-i-use-sktextureatlas-late/20892648#20892648): _"Sprite Kit also employs a caching mechanism apparently, so even if the last strong reference to a resource file has been removed the file will remain in memory."_ – Luca Angeletti Jun 16 '16 at 14:47
-
Yeah I do not put faith in random people on Stack Overflow that use answers like apparently, without documentation. Nowhere in apple docs does it say this is happening. SKTextureAtlas will have a strong reference to all the textures, so if you want the atlas to be removed, you need to make sure that no sprite is using said texture, then make sure that you remove all references to your SKTextureAtlas. This will remove it from memory. Now if you have 1 reference to an atlas, and create a new instance of SKTextureAtlas, then perhaps I will believe that it will grab it from the cache – Knight0fDragon Jun 16 '16 at 14:56
-
@Knight0fDragon: "random people on Stack Overflow?" [Look](http://stackoverflow.com/tags/sprite-kit/topusers) at the top user for the SpriteKit tag :D it's the same person who provided the answer I linked you ;-) – Luca Angeletti Jun 16 '16 at 15:08
-
I just tested your Rule 1, that also fails, doing SKSpriteNode(imageNamed:"") creates a new texture, not using the atlas – Knight0fDragon Jun 16 '16 at 15:09
-
yes random user, doesn't matter how many posts they make on a tag, if they can't provide documentation or proof, then it is not an answer, it is a theory – Knight0fDragon Jun 16 '16 at 15:11
-
@Knight0fDragon: _"SpriteKit searches first for an image file with the specified filename. If it doesn’t find one, it searches __inside any texture atlases__ built into the app bundle."_ From [Apple Docs](https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9-SW15) – Luca Angeletti Jun 16 '16 at 15:19
-
You may want to report that as an apple bug then, because I am getting 2 different texture objects, it finds my image located inside the atlas, but it makes an entirely new texture – Knight0fDragon Jun 16 '16 at 15:21
-
@Knight0fDragon: Interesting, can you provide me the code you used to perform the test? – Luca Angeletti Jun 16 '16 at 15:28
-
I am sure you can follow the code to determine how to create your assets – Knight0fDragon Jun 16 '16 at 15:32
-
-
This answer should be pinned to the start of learning SpriteKit. @appzYourLife why does it search outside texture atlases first, then inside them? How can I make it search inside a specific textureAtlas so I can use the same name in different textureAtlases? – Confused Nov 21 '16 at 16:45