Free SKTextureAtlas From Memory

时间:2015-07-28 23:03:59

标签: ios swift memory-management sprite-kit sktextureatlas

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!

1 个答案:

答案 0 :(得分:2)

@dragoneye第一点是正确的:你必须只预加载SKTextureAtlas一次。

查看Apple的文档Working with Sprites

-

  1. 将纹理预加载到内存中
  2. 从内存中删除纹理
  3. 然后,如果没有释放内存,这可能是因为第二点所指向的SKTexture仍然存在引用:

      

    将纹理加载到图形硬件的内存后,它将保留在内存中,直到删除引用SKTexture对象为止。这意味着在级别之间(或在动态游戏中),您可能需要确保删除纹理对象。通过删除对它的任何强引用来删除SKTexture对象对象,包括:

         
        
    • 游戏中SKSpriteNodeSKEffectNode个对象的所有纹理参考
    •   
    • 您自己代码中对纹理的任何强引用
    •   
    • 用于创建纹理对象的SKTextureAtlas对象
    •