Swift SceneKit在场景内存泄漏之间切换
我有两个没有任何节点和摄影机的空白scnscene对象:Swift SceneKit在场景内存泄漏之间切换,swift,memory-leaks,scenekit,Swift,Memory Leaks,Scenekit,我有两个没有任何节点和摄影机的空白scnscene对象: func setupScenes() { scnView = SCNView(frame: self.view.frame) self.view.addSubview(scnView) gameScene = SCNScene(named: "/MrPig.scnassets/GameScene.scn") splashScene = SCNScene(named: "/MrPig.scnassets/Splas
func setupScenes() {
scnView = SCNView(frame: self.view.frame)
self.view.addSubview(scnView)
gameScene = SCNScene(named: "/MrPig.scnassets/GameScene.scn")
splashScene = SCNScene(named: "/MrPig.scnassets/SplashScene.scn")
scnView.scene = splashScene
}
显示每个scnscene的两种方法:
func startSplash() {
gameScene.isPaused = true
let transition = SKTransition.doorsOpenVertical(withDuration: 1.0)
scnView.present(splashScene, with: transition, incomingPointOfView: nil, completionHandler: {
self.gameState = .tapToPlay
self.setupSounds()
self.splashScene.isPaused = false
})
}
func startGame() {
splashScene.isPaused = true
let transition = SKTransition.doorsOpenVertical(withDuration: 1.0)
scnView.present(gameScene, with: transition, incomingPointOfView: nil, completionHandler: {
self.gameState = .playing
self.setupSounds()
self.gameScene.isPaused = false
})
}
和触摸手势,用于在SCN之间切换:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if gameState == .tapToPlay {
startGame()
} else {
startSplash()
}
}
override func touchsbegind(touch:Set,带有事件:UIEvent?){
如果游戏状态==.tapToPlay{
startGame()
}否则{
startSplash()
}
}
每次我触摸屏幕时,屏幕上会出现第一个或第二个scnscene,我使用了大约80Mb的RAM。
触摸10次后,500兆内存已经使用
我不明白为什么会发生这种情况?代码中的一个明显问题是,每次调用startGame()和startSplash()方法时,带有闭包的嵌套函数都会通过强引用捕获“自我” 关于强引用和弱引用的一些信息 首先,您应该执行以下操作:
func startSplash() {
gameScene.isPaused = true
let transition = SKTransition.doorsOpenVertical(withDuration: 1.0)
scnView.present(splashScene, with: transition, incomingPointOfView: nil, completionHandler: { [weak self] in
guard let self = self else { return }
self.gameState = .tapToPlay
self.setupSounds()
self.splashScene.isPaused = false
})
}
func startGame() {
splashScene.isPaused = true
let transition = SKTransition.doorsOpenVertical(withDuration: 1.0)
scnView.present(gameScene, with: transition, incomingPointOfView: nil, completionHandler: { [weak self] in
guard let self = self else { return }
self.gameState = .playing
self.setupSounds()
self.gameScene.isPaused = false
})
}
第二,尽量不要使用触摸法,因为它可能会导致一些副作用
希望有帮助 我遇到了完全相同的问题,无法找出原因,但我想这与spritekit有关,特别是当您同时使用metal和scenekit时。看见
当前(场景…)来自spritekit。我提出的唯一解决方案是直接设置场景和SCNView的视点,而不是通过当前的(…)方法 最好检查内存图或分析器以找到真正的罪魁祸首。