“致命错误:在解开可选值时意外发现 nil"在调用协议方法时 [英] "fatal error: unexpectedly found nil while unwrapping an Optional value" while calling a protocol method
问题描述
我已经实现了一个协议来获取某种消息,即游戏已经完成并将时间传递给我的控制器(游戏用 SpriteKit 编写).但是现在我在完成游戏并执行 gameEnded 方法后遇到了这个致命错误并且应用程序崩溃了.有谁知道为什么?
I've implemented a protocol to get some sort of message, that a game has already finished and passes the time to my controller (Game wrote in SpriteKit). But now I'm having this fatal error after finishing the game and executing the gameEnded method and the app just crashes. Does anyone know why?
这是我的代码
GameViewController
GameViewController
class AcceleratorGameController: UIViewController {
var time: Float = 0.0
var challengeController: ChallengeViewController!
weak var delegate : GameEnded?
override func viewDidLoad() {
super.viewDidLoad()
if let scene = AcceleratorGame.unarchiveFromFile("AcceleratorGame") as? AcceleratorGame {
let skView = self.view as! SKView
skView.showsFPS = true
scene.viewController = self
skView.ignoresSiblingOrder = true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var dest : ChallengeViewController = segue.destinationViewController as! ChallengeViewController
dest.gameHasFinished(time) //Dont know if this does anything...
println("Segue now!")
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(true)
println("View will disapear")
delegate.gameHasFinished(self.time) // ###CRASHES HERE!###
}
这是我的另一个 ViewController
Here is my other ViewController
protocol GameEnded : class {
func gameHasFinished(time: Float)
}
class ChallengeViewController : UIViewController, GameEnded {
var time : Float = 0.0
var acceleratorGameController : AcceleratorGameController!
override func viewDidLoad() {
super.viewDidLoad()
println("ChallengeViewController geladen")
startGame()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "accelGame" {
acceleratorGameController = segue.destinationViewController as! AcceleratorGameController
acceleratorGameController.delegate = self
}
}
func startGame () {
println("Start Game")
self.showAccelGameView()
}
func gameHasFinished(time: Float) {
println("Game has finished")
self.time = time
}
func showAccelGameView() {
println("Show Accel Game")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("AcceleratorGameController") as! AcceleratorGameController
self.navigationController?.pushViewController(vc, animated: true)
}
我做了你告诉我的所有事情,但它仍然在同一点崩溃.Xcode 告诉我使用委托.我什么时候委托?它有效,但这不是我想要的.必须调用该函数!
I did all the things that you told me to, and it still crashes at the same point. Xcode told me to use a delegate. When I do delegate? It works, but that's not what I want. That function has to be called!
func gameOver(time: Float) {
println("Game Over")
self.time = time
//delegate!.gameHasFinished(time) still crashes here. added !. i commented it to test the prepareForSegue method
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var dest : ChallengeViewController = segue.destinationViewController as! ChallengeViewController
dest.gameHasFinished(time)
println("Segue now!") // Wont happen
self.navigationController?.popViewControllerAnimated(true) //Wont happen either. If i call this in gameOver() it works.
}
我在 prepareForSegue()
方法中加入了一些 println()
,但不知何故它们不会被执行.我必须以某种方式打电话给他们吗?这是我的转场截图.
I've put in some println()
in the prepareForSegue()
methods, but somehow they won't get executed. Do I have to call them somehow? Here is a screenshot of my segue.
http://i.stack.imgur.com/oK4Ce.png
我也试过以另一种方式放入一个转场,但也无济于事.
I also tried putting in one segue the other way round, but it doesn't help either.
http://i.stack.imgur.com/TVmdP.png (没有标识符,因为它是唯一的转场.)
http://i.stack.imgur.com/TVmdP.png (no identifier because it's the only segue.)
我忘了说这个 AcceleratorGameController
背后的 SpriteKit Game 在它完成时调用了 gameOver()
方法.
I forgot to say that the SpriteKit Game behind this AcceleratorGameController
calls the gameOver()
method when it has finished.
推荐答案
我不明白 ChallengeViewController
将如何初始化 AccelerometerGameController
的委托.
I don't see how ChallengeViewController
will initialize the delegate of AccelerometerGameController
.
在您的 prepareForSegue
中,只有当 segue 标识符为 accelGane
时,您才为 GameController 设置委托.但是在 showAccelGameView
中触发 segue 时,您没有使用此标识符.如果您的故事板中已经设置了转场,请使用它来触发转场
In your prepareForSegue
, you are setting the delegate for the GameController only if the segue identifier is accelGane
. But when firing the segue in showAccelGameView
, you are not using this identifier. If you already have the segue setup in your storyboard, use this to fire the segue
self.performSegueWithIdentifier("accelGane", sender: self)
这篇关于“致命错误:在解开可选值时意外发现 nil"在调用协议方法时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!