“致命错误:在解开可选值时意外发现 nil"在调用协议方法时 [英] "fatal error: unexpectedly found nil while unwrapping an Optional value" while calling a protocol method

查看:37
本文介绍了“致命错误:在解开可选值时意外发现 nil"在调用协议方法时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个协议来获取某种消息,即游戏已经完成并将时间传递给我的控制器(游戏用 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆