Быстро, как вернуть память в нормальное состояние после удаления SKScene?
Я создал простую игру с SpriteKit, но каждый раз, когда я запускаю игру, использование памяти в симуляторе увеличивается примерно на 30 мб, но никогда не уменьшается, когда игра заканчивается.
Когда я запускаю игру более чем в десять раз, симулятор становится все медленнее и медленнее и в конечном итоге падает.
В этой простой игре у меня есть два контроллера и gamescene:
MainController вызывает GameViewController с помощью кнопки
В GameViewController инициализируется gamecene следующим образом:
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)
Я также попытался применить методы удаления в Deanit в GameScene:
deinit{
self.removeAllActions()
self.removeAllChildren()
}
По-прежнему не работает
Ответы
Ответ 1
Ваш GameViewController
имеет сильную ссылку на ваш GameScene
. И ваш GameScene
имел сильную ссылку на ваш GameViewController
. Это приводит к сильному эталонному циклу, что означает, что ни один объект не будет освобожден.
Вам нужно объявить свойство viewController в вашем GameScene
слабым.
weak var viewController:GameViewController? = GameViewController()
Ответ 2
Использование Swift 3, Xcode 8 и iOS 10.
После того, как вы отказались от сильных ссылок, позаботились о SKTextures и т.д. Уровень памяти не восстановился после увольнения сцены и возврата в "menu" viewController.
Я использовал:
override func sceneDidLoad() {...}
Это доступно в iOS 10, но мне нужна совместимость с iOS 8 и 9, поэтому я
изменено на старшее:
override func didMove(to view: SKView) {...}
Помимо совместимости со старыми версиями iOS, оказывается, что уровень памяти падает после увольнения сцены. Это был сюрприз. Я пропускаю, вероятно, некоторые утечки, но он работает на меня.
Надеюсь, это поможет кому-то.