我有两个没有任何节点和照相机的空白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/SplashScene.scn")
scnView.scene = splashScene
}
两种显示每个场景的方法:
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
})
}
以及用于在场景之间切换的触摸手势:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if gameState == .tapToPlay {
startGame()
} else {
startSplash()
}
}
每次触摸屏幕时,屏幕上都会出现第一个或第二个场景,并且我习惯了〜80Mb的RAM。 经过10次接触后,已经使用了500MB的RAM。
我不明白为什么会这样?
答案 0 :(得分:0)
代码中明显的问题是,每次调用startGame()和startSplash()方法时,带有闭包的嵌套函数都会捕获具有强引用的“自我”。
有关强引用和弱引用以及ARC的一些信息。
首先,您应该执行以下操作:
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
})
}
第二,尽量不要使用touchesBegan方法,这可能会导致一些副作用。
希望有帮助!
答案 1 :(得分:0)
我遇到了完全相同的问题,无法找到原因,但是我想这与spritekit有关,特别是当您将Metal和Scenekit一起使用时。参见scenekit spritekit memory leak。 present(场景...)来自spritekit。我想出的唯一解决方案是直接设置场景和SCNView的视点,而不是通过present(...)方法。