在swift中,如何在删除SKScene后让内存恢复正常?

时间:2015-06-17 13:18:27

标签: swift memory sprite-kit skscene

我使用SpriteKit创建了一个简单的游戏,但每次运行游戏时,模拟器中的内存使用量增加约30mb,但在游戏结束时不会减少。

当我运行游戏超过十次时,模拟器变得越来越慢并最终崩溃。

在这个简单的游戏中,我有两个控制器和一个gamecene:

MainController通过触发按钮调用GameViewController

在GameViewController中,gamescene以这种方式初始化:

class GameViewController: UIViewController
{

  var skView:SKView!

  var scene:GameScene!

  override func viewDidLoad() {

      super.viewDidLoad()
      scene = GameScene(size: view.bounds.size)
      skView = view as SKView
      skView.ignoresSiblingOrder = true
      scene.scaleMode = .ResizeFill

      scene.viewController = self
      skView.presentScene(scene)

  }

//with a prepareForSegue deinitialises the scene and skview:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    if segue.identifier == "GameFinished"{

        scene.removeAllActions()
        scene.removeAllChildren()
        scene.removeFromParent()
        scene = nil

        skView.presentScene(nil)
        skView = nil

        let target = segue.destinationViewController as MainController
    }
  }
}

在GameScene中,viewController是一个属性

var viewController:GameViewController? = GameViewController()

用以下方式触发segue:

self.viewController!.performSegueWithIdentifier("GameFinished", sender: nil)

我还试过在GameScene中将删除方法放入deinit:

  deinit{
    self.removeAllActions()
    self.removeAllChildren()
  }

仍然无法运作

2 个答案:

答案 0 :(得分:8)

您的GameViewController强烈引用了您的GameScene。并且您的GameScene强烈引用了您的GameViewController。这导致强大的参考周期,这意味着两个对象都不会被释放。

您需要将GameScene中的viewController属性声明为弱。

weak var viewController:GameViewController? = GameViewController()

答案 1 :(得分:0)

使用Swift 3,Xcode 8和iOS 10。 在避免强引用后,照顾SKTextures等等。在解除场景并返回到菜单后,内存级别没有恢复。的viewController。 我正在使用:

override func sceneDidLoad() {...}

这在iOS 10中可用,但我想要iOS 8& 9兼容性,这就是为什么我会这样做的原因 变成了旧的:

override func didMove(to view: SKView) {...}

除了与旧的iOS版本兼容之外,事实证明在解除场景后内存级别下降。这是一个惊喜。我可能遗漏了一些漏洞,但它为我工作。 我希望它对某人有帮助。