Swift:解包nil会导致我的程序崩溃

时间:2017-10-04 20:10:15

标签: swift

我是新手,我正在学习Udemy的课程。

我收到了错误

“主题1:EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)”

并且控制台将其解释为“在解开可选值时意外发现nil”。

我已经仔细检查以确保我的代码与我的教师的代码完全相同,甚至重新启动一次以防我搞砸了但我仍然遇到同样的错误。

我的代码如下:

    import UIKit
    import AVFoundation

    class ViewController: UIViewController {
        @IBOutlet weak var darkBlueBG: UIImageView!
        @IBOutlet weak var powerButton: UIButton!
        @IBOutlet weak var cloudHolder: UIView!
        @IBOutlet weak var rocket: UIImageView!
        @IBOutlet weak var hustleLbl: UILabel!
        @IBOutlet weak var onLbl: UILabel!

        var player: AVAudioPlayer!

        override func viewDidLoad() {
            super.viewDidLoad()

            let path = Bundle.main.path(forResource: "hustle-on", ofType: "wav")! //This is the line that the console says is causing the error
            let url = URL(fileURLWithPath: path)

            do {
                player = try AVAudioPlayer(contentsOf: url)
                player.prepareToPlay()
            } catch let error as NSError {
                print(error.description)
            }
        }


        @IBAction func powerButtonPressed(_ sender: Any) {
            cloudHolder.isHidden = false
            darkBlueBG.isHidden = true
            powerButton.isHidden = true

            player.play()

            UIView.animate(withDuration: 2.3, animations: {
            self.rocket.frame = CGRect(x: 0, y: 20, width: 375, height: 402)
            }) { (finished) in
                self.hustleLbl.isHidden = false
                self.onLbl.isHidden = false

            }
        }
    }

3 个答案:

答案 0 :(得分:2)

请阅读path方法的文档:

https://developer.apple.com/documentation/foundation/bundle/1409670-path

它声明此方法可以返回nil

  

返回值

     

资源文件的完整路径名,如果是,则为nil   无法找到档案。

因此,您应采取适当的预防措施,方法是使用guard或使用if let展开可选项,以防止崩溃。

示例:

if let path = Bundle.main.path(forResource: "hustle-on", ofType: "wav") {
    // work with the path value
} else {
    // take appropriate action since path is nil!
}

guard
    let path = Bundle.main.path(forResource: "hustle-on", ofType: "wav") else{
        // take appropriate action since path is nil!
        return
   }

答案 1 :(得分:0)

根据您标记的行,看起来文件AND未包含在您的捆绑资源中。仔细检查您的项目中是否包含此文件。如果这样做,选择它并查看文件检查器,并仔细检查是否已选中目标。

答案 2 :(得分:0)

你永远不应该打开这样的可选项,而是使用guard或者如下所示:

guard let path = Bundle.main.path(forResource: "hustle-on", ofType: "wav") else {
    // Add some logic here because the file wasn't found. Then return because it failed.
    return
}

if let path = Bundle.main.path(forResource: "hustle-on", ofType: "wav") {
    let url = URL(fileURLWithPath: path)

    do {
        player = try AVAudioPlayer(contentsOf: url)
        player.prepareToPlay()
    } catch let error as NSError {
        print(error.description)
    }
}

然后它只会尝试使用路径,如果它从Bundle.main.path调用回来。