清除SKTextureAtlas
的缓存实例时,我遇到一个非常奇怪的问题。
简而言之,在游戏开始之前,我使用SKTextureAtlas
预加载textureAtlas.preload(completionHandler:)
,并在完成处理程序中将对atlas的引用存储在私有属性中,以便将其保存在内存中以后的使用。
过了一会儿,这个纹理图集不再需要了,我想摆脱它,以保持清洁和健康的记忆。
问题
我遇到的问题是,当我清除纹理图集时(通过将对图集的引用设置为nil
的设置),性能会急剧下降几秒钟。大幅度上,我的意思是从60fps到40fps不变。
请注意,肯定此处没有其他对该地图集的引用。
有趣:第1部分
仅在iOS 10上发生。在iOS 9上完美运行,即使在较旧的设备上也是如此。
有趣:第2部分
仅在.spriteatlas
内以.xcassets
的形式定义地图集时才会发生。但如果地图集是.atlas
之外的.xcassets
文件夹,则不会。
我知道我可以继续使用.atlas
代替.spriteatlas
,但是.spriteatlas
支持应用稀疏开箱即用.atlas
“T
有趣:第3部分
如果地图集中包含少量小纹理,则清除工作正常。这表明可能存在与地图集总大小相关的内部问题。但为什么呢?
动机
找到此问题的解决方案/解决方法背后的动机是批量绑定/绘制调用。使用相同纹理的子节点都在一个绘制过程中渲染,这当然会大大提高性能。
有了这个问题,我基本上不得不创建多个地图集,这反过来会导致多次绘制调用,从而影响整体性能。
非常感谢任何帮助。
更新
我尝试过实施@ Knight0fDragon建议的解决方案,建议从SKTexture
而不是SKTextureAtlas
本身缓存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
和endAppearanceTransition
的调用,所以视图控制器生命周期方法(viewWillAppear:
,没有调用viewWillDisappear
),这正是我开始/停止所有动画的逻辑。因此动画继续在后台运行。
也就是说,即使动画在后台运行,它也不应该干扰完全不相关的东西,比如清除缓存的地图集。
注意:有问题动画的图像视图中的图像在有问题的纹理图集中定义为不。