0

清除缓存的SKTextureAtlas.

简而言之,在游戏开始之前,我预加载了SKTextureAtlaswithtextureAtlas.preload(completionHandler:)并在完成处理程序中将对图集的引用存储在私有属性中,以便将其保存在内存中以供以后使用。

一段时间后,不再需要这个纹理图集,我想摆脱它,以保持干净健康的记忆。

问题

我遇到的问题是,当我清除纹理图集时(通过将持有对图集的引用的属性设置为nil),性能会在几秒钟内急剧下降。我的意思是从恒定的 60fps 到 40fps。

请注意,此时绝对没有其他对该图集的引用。


有趣:第 1 部分

仅在 iOS 10 上发生。在 iOS 9 上完美运行,即使在更旧的设备上也是如此。

有趣:第 2 部分

仅当图集.spriteatlas.xcassets. 但如果地图集.atlas.xcassets.

我知道我可以继续使用.atlas 而不是.spriteatlas,但.spriteatlas支持开箱即用的应用程序细化,但.atlas事实并非如此。

有趣:第 3 部分

如果图集具有少量小纹理,则清除工作正常。这表明可能存在与图集总大小相关的内部问题。但为什么?

动机

为这个问题找到解决方案/解决方法的动机是批处理绑定/绘制调用。使用相同纹理的子节点都在一个绘制通道中渲染,这当然会大大提高性能。

有了这个问题,我基本上被迫创建多个图集,这反过来会导致多个绘制调用,从而影响整体性能。

任何帮助将不胜感激。


更新

我已经尝试实现@Knight0fDragon 建议的解决方案,它建议缓存SKTexturesSKTextureAtlas而不是SKTextureAtlas自身,但遗憾的是,这在我的情况下不起作用。

我在最初的问题中忘记提到的是,这个问题大多数时候都会发生,但并非总是如此。每次尝试约 5 次,我都能让它正常工作。


解决方案

由于在被错误地标记为重复后我无法重新打开我的问题,我将在这里发布我找到的解决方案。

问题是在后台运行的动画。这个动画是这样设置的

let rotation = CABasicAnimation(keyPath: "transform.rotation")
rotation.fromValue = 0
rotation.toValue = 2 * M_PI
rotation.duration = 110
rotation.repeatCount = Float.infinity

它运行在UIImageView. 这个图像视图位于最终呈现另一个包含游戏场景的视图控制器的视图控制器中。

这两个视图控制器之间的转换是自定义的,由于我忘记在自定义转换动画器中添加调用,因此没有调用视图控制器生命周期方法(beginAppearanceTransition, ),这正是我有启动/停止所有逻辑的地方动画。因此动画一直在后台运行。endAppearanceTransitionviewWillAppear:viewWillDisappear

也就是说,即使动画在后台运行,它也不应该干扰一些完全不相关的事情,比如清除缓存的图集。

注意:有问题的动画的图像视图中的图像没有在有问题的纹理图集中定义。

4

0 回答 0