“线程1:致命错误:在展开可选值时意外发现为零”

时间:2019-12-03 05:44:42

标签: swift xcode optional

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()
    }
}

3 个答案:

答案 0 :(得分:1)

如@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")
       }
   }}

答案 1 :(得分:0)

您的资源之一为零。 您应该(强行)解开包装之前检查您的资源是否为零:

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

对每种资源都执行此操作,然后使用调试器查看哪个资源为零。

答案 2 :(得分:0)

区分大小写很重要。

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

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

一种更有效的解决方案是创建一种方法来加载文件并播放声音并使用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()
    }
}