我需要在玩家完成关卡后释放playcene,以便内存可用于加载我游戏的另一个级别。如果我不这样做,由于内存问题,我的应用程序崩溃了。
我遵循了那里的指示:
Swift: Deallocate GameScene after transition to new scene?
但不幸的是,它对我不起作用。我收到错误"无法施展价值' UIView'到' SKView'在我的GameViewController类中。这是我的全部代码:
import Foundation
import UIKit
import SpriteKit
class GameViewController: UIViewController {
var scene1: SKScene?
var scene2: SKScene?
var scene3: SKScene?
var skView: SKView?
func nextSceneAction1() {
scene2 = nil
scene3 = nil
skView! = self.view as! SKView
skView!.showsFPS = true
skView!.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView!.ignoresSiblingOrder = true
scene1 = TransitionSigns(size: skView!.frame.size)
scene1!.size.width = 2048
scene1!.size.height = 1536
/* Set the scale mode to scale to fit the window */
scene1!.scaleMode = .AspectFill
let transition = SKTransition.revealWithDirection(.Right, duration: 2)
scene1!.scaleMode = .AspectFill
skView!.presentScene(scene1!, transition: transition)
}
func nextSceneAction2() {
scene1 = nil
scene3 = nil
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
scene2 = TransitionSigns(size: skView.frame.size)
scene2!.size.width = 2048
scene2!.size.height = 1536
/* Set the scale mode to scale to fit the window */
scene2!.scaleMode = .AspectFill
let transition = SKTransition.revealWithDirection(.Right, duration: 2)
scene2!.scaleMode = .AspectFill
skView.presentScene(scene2!, transition: transition)
}
func nextSceneAction3() {
scene1 = nil
scene2 = nil
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
scene3 = TransitionSigns(size: skView.frame.size)
scene3!.size.width = 2048
scene3!.size.height = 1536
/* Set the scale mode to scale to fit the window */
scene3!.scaleMode = .AspectFill
let transition = SKTransition.revealWithDirection(.Right, duration: 2)
scene3!.scaleMode = .AspectFill
skView.presentScene(scene3!, transition: transition)
}
override func viewWillLayoutSubviews() {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
let scene = MainView(size: skView.frame.size)
scene.size.width = 2048
scene.size.height = 1536
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
override func shouldAutorotate() -> Bool {
return true
}
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
if UIDevice.currentDevice().userInterfaceIdiom == .Phone {
return UIInterfaceOrientationMask.AllButUpsideDown
} else {
return UIInterfaceOrientationMask.All
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidDisappear(animated: Bool) {
self.view.removeFromSuperview()
}
override func viewWillDisappear(animated: Bool){
self.view.removeFromSuperview()
}
}
我通过以下方式调用其他类中的不同函数nextSceneAction1()
,nextSceneAction2()
和nextSceneAction3()
:
let controller1 = GameViewController()
controller1.nextSceneAction1()
或
let controller2 = GameViewController()
controller2.nextSceneAction1()
当加载新场景时,我收到此错误:"无法转换类型' UIView'到' SKView'。你知道这段代码有什么问题吗?
顺便说一句,在开始加载新场景之前,我打开所有其他可能性从内存中清除旧场景,以便在应用程序的生命周期内没有内存崩溃。
答案 0 :(得分:2)
一般情况下,SKScene会在您转换到新场景后自动解除分配,除非您有内存泄漏,因此通常您不必为了释放内存而特别做任何事情。
要查看您的场景是否已取消分配,您可以添加deinit方法
func deinit {
print("scene did deallocate")
}
如果在更改场景时调用此方法,则您知道所有内容都已正确解除分配,如果未调用它,则会发生内存泄漏。
此外,您的代码有问题,您每次更改场景时都会创建一个新的GameViewController实例,而不是访问当前实例。
let controller2 = GameViewController() // creates new instance of GameViewController
controller2.nextSceneAction1()
您通常只从GameViewController加载第一个场景,而且所有其他场景更改都可以直接在您所在的SKScene中完成。不要为此使用GameViewController。
在您当前的SKScene中,您可以更改为这样的新场景(例如从GameScene到MenuScene)
class GameScene: SKScene {
...
func loadMenuScene() {
let menuScene = MenuScene(size: self.size) // use size of current scene
let transition = Some SKTransition
view?.presentScene(menuScene, withTransition: transition)
}
}
希望这有帮助