Swift SceneKit在场景内存泄漏之间切换

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

我有两个没有任何节点和摄影机的空白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
}
显示每个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的视点,而不是通过当前的(…)方法

最好检查内存图或分析器以找到真正的罪魁祸首。