"Thread1:Fatal error:Unexpectedly found nil while unwrapping an Optional value"

"Thread1:Fatal error:Unexpectedly found nil while unwrapping an Optional value"

1这些是我用的wav文件

2我附上了它抛出此错误的位置的屏幕截图。

这就是我现在拥有的。我以为我一切都正确。我知道这与使用可选但不确定如何修复它有关。

import UIKit
import AVFoundation

class SecondViewController: UIViewController
{
    var audioPlayer: AVAudioPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        do
        {
            let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
            let horseSound = Bundle.main.path(forResource: "Horse", ofType: "wav")
            let dogSound = Bundle.main.path(forResource: "Dog", ofType: "wav")
            let raccoonSound = Bundle.main.path(forResource: "Raccoon", ofType: "wav")

            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound!))
            audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound!))
        }
        catch
        {
            print(error)///
        }
    }

    @IBAction func cat(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func horse(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func dog(_ sender: Any)
    {
        audioPlayer?.play()
    }
    @IBAction func raccoon(_ sender: Any){
        audioPlayer?.play()
    }
}

您的一项资源为零。 在(强行)打开它之前,你应该检查你的资源是否为零:

if let catSound = Bundle.main.path(forResource: "Cat", ofType: "wav")
{
    audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
}

对每个资源执行此操作并使用调试器查看哪个为零。

如@Chris 和@inexcitus 所述,您的完整代码如下所示。

class SecondViewController: UIViewController {

    var audioPlayer: AVAudioPlayer?
    override func viewDidLoad() {
      super.viewDidLoad()
    }

    @IBAction func cat(_ sender: Any)
    {
       if  let catSound = Bundle.main.path(forResource: "cat", ofType: "wav") {
           audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: catSound))
           audioPlayer?.play()
       }else {
        print("Cat File is missing")
       }

    }
    @IBAction func horse(_ sender: Any)
    {
       if  let horseSound = Bundle.main.path(forResource: "horse", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: horseSound))
          audioPlayer?.play()
       }else {
        print("Horse File is missing")
       }
    }


    @IBAction func dog(_ sender: Any)
    {
       if  let dogSound = Bundle.main.path(forResource: "dog", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: dogSound))
          audioPlayer?.play()
       }else {
        print("Dog File is missing")
       }
    }
    @IBAction func raccoon(_ sender: Any)
    {
       if  let raccoonSound = Bundle.main.path(forResource: "raccoon", ofType: "wav") {
          audioPlayer = try? AVAudioPlayer(contentsOf: URL(fileURLWithPath: raccoonSound))
          audioPlayer?.play()
       }else {
        print("Raccoon File is missing")
       }
   }}

区分大小写很重要。

文件是小写的 ("cat"),但代码中的参数字符串是大写的 ("Cat")。参数字符串和文件名必须完全匹配。

您的代码无论如何都不是很有用,因为它在 viewDidLoad 中三次覆盖了音频播放器实例。

一个更有效的解决方案是创建一个方法来加载文件和播放声音,并使用 Bundle 的 URL 相关 API。

强制解包很好,因为所有文件都必须在编译时 时在包中。可以立即修复设计错误(文件丢失或名称拼写错误)。

class SecondViewController: UIViewController
{
    var audioPlayer: AVAudioPlayer!

    @IBAction func cat(_ sender: Any) {
        playSound(withName: "cat")
    }

    @IBAction func horse(_ sender: Any) {
        playSound(withName: "horse")
    }

    @IBAction func dog(_ sender: Any) {
        playSound(withName: "dog")
    }

    @IBAction func raccoon(_ sender: Any){
        playSound(withName: "raccoon")
    }

    func playSound(withName name : String) {
        let sound = Bundle.main.url(forResource: name, withExtension: "wav")!
        audioPlayer = try! AVAudioPlayer(contentsOf: sound)
        audioPlayer.play()
    }
}