【发布时间】:2019-01-30 17:10:43
【问题描述】:
我目前有一个 Assets 单例类,可让我访问纹理、声音和音乐。作为我的合作伙伴和我正在经历我们项目的内存管理阶段,我们已经意识到我们可能会产生严重的泄漏,并且基于我对 Xcode 工具的使用,我们最大的问题可能集中在这个单例类上。虽然肯定存在其他漏洞,但我们注意到当在地图屏幕和游戏屏幕之间来回移动时,有大约 100 mb 的相当稳定的增长,这似乎对应于我们的 11 个地图资产。在这种情况下,我的问题是:
下面的代码是否会创建一个保留循环,如果是,是否可以通过单例类的存在来管理它,或者我们是否应该打破这个东西。纹理图集分开保存?
func transitionToMapScreen()
{
//I hope this isn't necessary eventually, but we were trying to ensure all game textures and emitters were deallocated
Assets.sharedInstance.deallocateGameAssets()
gameScene = GameScene()
Assets.sharedInstance.preloadMap
{
[unowned self] in
let mapScene = MapScreen(fileNamed: "MapScreen")!
mapScene.preCreate()
mapScene.scaleMode = self.scaleMode
// Transition with a fade animation
let reveal = SKTransition.fade(withDuration: 2.0)
let fadeMusic = SKAction.run
{
Assets.sharedInstance.bgmTitlePlayer?.setVolume(1.0, fadeDuration: 1.0)
Assets.sharedInstance.bgmTitlePlayer?.play()
Assets.sharedInstance.bgmGamePlayer?.setVolume(0.0, fadeDuration: 1.0)
}
let stopGameMusic = SKAction.run
{
Assets.sharedInstance.bgmGamePlayer?.stop()
}
let transitionAction = SKAction.run
{
self.view?.presentScene(mapScene, transition: reveal)
}
self.run(SKAction.sequence([SKAction.wait(forDuration: 1.0), fadeMusic, SKAction.group([stopGameMusic, transitionAction])]))
} // end Assets.sharedInstance.preloadMap completion block*/
}
根据我对 Swift 中保留周期的了解,这不是创建对 Assets 类的自引用并造成内存泄漏吗?这能解释我们的地图资产在内存中保留的行为吗?如果是这样,管理此问题的正确方法是什么?
【问题讨论】:
-
如果存在保留周期和泄漏,Instruments 或 Memory Graph 会告诉您。
-
我不确定,但您的 Assets.sharedInstance 可能会保留自己。
-
matt,我确实看到了与此相关的泄漏,但使用的字节非常小。也许这是我对分配的不熟悉,但这是否表明如果我看到内存使用量急剧上升,那么在 4-5 分钟的游戏会话中使用的
-
当然,我同意。但问题是我不确定为什么会发生这种情况,因为 SK 有一些令人困惑的行为。特别是,尽管事先解除了这些资产的分配,但一旦所述预加载完成,我看到进入某些场景时不会发生某些预加载。这令人困惑,但在进一步阅读之后,似乎 SK 有时会有意无意地将资产保存在内存中。所以我看到了这种行为,我没有看到与之相关的泄漏,但我确实看到我的纹理图集中的仪器的内存使用量急剧上升。
-
澄清一下:我目前基于 Instruments 的猜测是,这不是 Assets 单例的保留周期问题(我们顺便消除了 - 显然,每个人都认为单例是邪恶的),而是 SK 在预加载某些资产后有意保留它们。我们有很大的纹理图集,我们正在缩小这些图集以测试该理论。我认为这篇文章对这个话题特别有用:stackoverflow.com/questions/37119707/…
标签: swift memory-management memory-leaks sprite-kit retain-cycle