SceneKit переключается между утечкой памяти сцены - PullRequest
0 голосов
/ 27 января 2019

У меня есть два пустых объекта 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
    })
  }

И сенсорный жест для переключения между сценами:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if gameState == .tapToPlay {
            startGame()
        } else {
            startSplash()
        }
    }

Каждый раз, когда я касаюсь экрана, на экране появляется первая или вторая сцена, и я использую плюс ~ 80 МБ ОЗУ.После 10 раз касаясь 500 МБ оперативной памяти уже используется.

Я не понимаю, почему это происходит?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

У меня была точно такая же проблема, и я не мог определить причину, но я думаю, что это как-то связано со спрайтекитом, особенно когда вы используете металл и сцену рядом друг с другом.см. утечка памяти в спрайтеки * .настоящее (сцена ...) из спрайтекита.единственное решение, которое я придумал, было установить сцену и точку обзора SCNView напрямую, а не с помощью метода present (...).

0 голосов
/ 28 января 2019

Очевидная проблема в вашем коде состоит в том, что каждый раз, когда вы вызываете методы 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, который может привестик некоторым побочным эффектам.

Надеюсь, это поможет!

...