I have a problem getting a texture atlas to free. Currently I have a SpriteKit game where a player can change his character. Right now I have the atlas's in a Global shared instance like so.
let char0Atlas: SKTextureAtlas = SKTextureAtlas(named: "Atlas/iPhone/char0")
let char1Atlas: SKTextureAtlas = SKTextureAtlas(named: "Atlas/iPhone/char1")
let char2Atlas: SKTextureAtlas = SKTextureAtlas(named: "Atlas/iPhone/char2")
Each character you can change to has their own texture atlas. I fetch player movement, idle, and jump animations from that characters atlas with a method like this:
func charAnimation(char: CharEnum) -> [SKTexture] {
var temp: [SKTexture] = []
var name: String = ""
let atlas: SKTextureAtlas = char.atlasForChar()
for i in 1...20 {
if i > 9 { name = "char_\(charId)_idle_00\(i)" }
else { name = "char_\(charId)_idle_000\(i)" }
temp.append(atlas.textureNamed(name))
}
return temp
}
And that is stored in an array instance variable in the player sprite node class. So every time a character is changed, these frames are replaced with the new frames, so the old ones should be freed correct?
class PlayerNode: SpriteNode {
private var currentAnimation: [SKTexture] = []
private var animations: (idle: [SKTexture], run: [SKTexture], jump: [SKTexture]) = PlayerController.animationsForHero(.CharOne)
}
Also, when the player switches characters, I use this to preload the texture atlas:
SKTextureAtlas.preloadTextureAtlases([char.atlasForHero()], withCompletionHandler: { () -> Void in
updateChar()
})
Why is SpriteKit never freeing the memory from the previous character animations? If the player switches to new characters, the memory constantly increases and crashes the app. If a character who was already chosen in that session is chosen again, the memory does not increase. This shows a memory leak. The characters animations are not being freed. Why?
I understand SpriteKit is supposed to take care of this stuff by itself, so that's why it's confusing. Is there absolutely no way to free a texture atlas myself manually?
Thanks!
答案 0 :(得分:2)
@dragoneye第一点是正确的:你必须只预加载SKTextureAtlas
一次。
查看Apple的文档Working with Sprites:
-
然后,如果没有释放内存,这可能是因为第二点所指向的SKTexture
仍然存在引用:
将纹理加载到图形硬件的内存后,它将保留在内存中,直到删除引用
SKTexture
对象为止。这意味着在级别之间(或在动态游戏中),您可能需要确保删除纹理对象。通过删除对它的任何强引用来删除SKTexture
对象对象,包括:
- 游戏中
SKSpriteNode
和SKEffectNode
个对象的所有纹理参考- 您自己代码中对纹理的任何强引用
- 用于创建纹理对象的
SKTextureAtlas
对象