Sprite kit,从内存中删除动画纹理

4

我在游戏加载时像这样初始化了大约30个动画纹理:

for i=0; i<atlasName.count; i++ {
        frameNumber = animationTextures.animationTextureAtlas[i].textureNames.count
        firstFrameName = "\(atlasName[i])1"

        animationTextures.animationFrames.append([animationTextures.animationTextureAtlas[i].textureNamed(firstFrameName)])

        for j=2; j<=frameNumber; j++ {
            var frameName = "\(atlasName[i])\(j)"
            animationTextures.animationFrames[i].append(animationTextures.animationTextureAtlas[i].textureNamed(frameName))
        }

        animationTextures.firstFrame.append(animationTextures.animationFrames[i][0])
    }

基本上,我将所有的动画都放入一个数组中,这样就可以很容易地访问它们。
在游戏中,每个动画都会出现一小段时间,当我不再需要它们时,使用.removeFromParent()删除它,但问题是它仍然停留在设备的内存中,因此一旦大约有15-20个动画出现在游戏中并进入内存时,它会达到大约450-500MB,并在iPhone 4和4s上崩溃。
有人知道如何真正从内存中删除该动画,使其不再占用空间吗?

我可以告诉你一个事实,SpriteKit内置了一个自动化的内存管理系统,专门用于这种情况。如果纹理数据占用太多空间,它将自动释放。我认为问题不一定在于纹理本身(除非你有很多),而且崩溃可能与你对这些纹理所做的操作有关。 - MaxKargin
1
这里有一些关于此问题的有用帖子: https://dev59.com/uWIk5IYBdhLWcg3wdd_Y#21541819, https://dev59.com/02025IYBdhLWcg3wpHl_ - Whirlwind
这几乎听起来像是一些事情的组合。第一,也许你没有重复使用纹理,即使你把它们放入了一个数组中。第二,即使你调用了 removeFromParent(),你仍然有一个对精灵的引用。此外,你可能需要查看你创建的数组。当你将变量命名为 frameNumber 时,实际上它们是计数等等,这很难跟踪。你的数组可能比预期的要大得多。希望这可以帮助你。 - Skyler Lauren
谢谢大家的回答,我发现问题出在菜单屏幕上循环运行的两个动画,而不是实际游戏中的动画。 - Mario Plantosar
1个回答

4

SpriteKit使用自己的缓存机制,您无法自行清除缓存。

根据您所说的情况,您的代码中可能存在内存泄漏。请记住,您需要删除所有对纹理的引用,以便ARC进行解除分配。

在您的情况下,仅从父级中删除纹理是不够的,因为这些纹理存储在数组中。您需要从数组中删除所有纹理,并且没有其他对它们的引用,才能正确释放它们。

仅几个纹理就达到450MB+绝对太多了。我建议您运行Instruments并检查内存泄漏。


谢谢你的回答,我知道你所说的关于ARC和删除所有引用的事情。在搜索内存泄漏和分配方面后,我发现问题实际上是菜单屏幕上循环运行的两个动画。每次循环开始时,它会分配一大堆内存,并且当达到约180MB时停止。 - Mario Plantosar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接