代码之家  ›  专栏  ›  技术社区  ›  Mitchell

xcode9 swift4致命错误:在展开可选值时意外发现零

  •  0
  • Mitchell  · 技术社区  · 8 年前

    当应用程序启动时,我正在尝试播放mp3文件(5秒),我不断收到错误:

    线程1:致命错误:在展开可选值时意外发现nil

    import UIKit
    import AudioToolbox
    
    class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    
        //create SystemSoundID
        var soundID:SystemSoundID = 0
        let path = Bundle.main.path(forResource: "iPhone100Voice", ofType: "mp3")
        let baseURL = NSURL(fileURLWithPath: path!)
        AudioServicesCreateSystemSoundID(baseURL, &soundID)
        //play
        AudioServicesPlaySystemSound(soundID)
    
        }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
        }
    
    }
    

    有人能解释一下我为什么以及如何解决这个问题吗?

    4 回复  |  直到 8 年前
        1
  •  1
  •   vadian    8 年前

    检查这些点,所有条件必须为真:

    • 文件是否在项目导航器中?
    • Target Membership 选中文件检查器中的复选框(要获取它,请选择文件并按 1. )
    • 文件名拼写是否正确( iPhone100Voice.mp3 )?
        2
  •  0
  •   Jogendar Choudhary    8 年前

    请检查您的文件名,可能文件名不正确或不在捆绑包中

    所以请检查文件名和扩展名。

    使用 if let guard unwrap 路径:

    override func viewDidLoad() {
    
        super.viewDidLoad()
        var soundID:SystemSoundID = 0
    
        if let path = Bundle.main.path(forResource: "iPhone100Voice", ofType: "mp3") {
           let baseURL = NSURL(fileURLWithPath: path)
           AudioServicesCreateSystemSoundID(baseURL, &soundID)
           AudioServicesPlaySystemSound(soundID)
        } else {
            let alert = UIAlertController(title: "Alert", message: "File not found in your bundle", preferredStyle: UIAlertControllerStyle.alert)
            alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
            self.present(alert, animated: true, completion: nil)
    
       }
    }
    
        3
  •  0
  •   Malleswari    8 年前

    播放视频可能对你有帮助。将视频文件添加到项目中时,请确保在文件检查器中选中或未选中目标复选框。

    override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(true)
    
    
            if  let path = Bundle.main.path(forResource: "video_1523966087401 (1)", ofType: ".mp4"){
                let player = AVPlayer(url: URL(fileURLWithPath: path))
                let playerController = AVPlayerViewController()
                playerController.player = player
                present(playerController, animated: true) {
                    player.play()
                }
            }else{
                //show dialog to user
    
                print("Error: File not found")
            }
        }
    
        4
  •  -1
  •   Ankur Lahiry    8 年前

    ! 表示崩溃运算符,它展开可选值。例如,Value there的作用类似于Optional(53)。因此,变量应包含除nil以外的值 path! 尝试展开可选项并在path变量中附加值53。

    要解决这个问题,我们可以使用两种方法

    使用防护装置,

    guard let pathValue = path else {
            return
    }
    
    let baseURL = NSURL(fileURLWithPath: pathValue) //no need to use pathValue, if you use then you have to use path!, although it makes no crash now.  
    AudioServicesCreateSystemSoundID(baseURL, &soundID)
    //play
    AudioServicesPlaySystemSound(soundID)
    

    如果path为nil,则它进入块并返回,如果它有值,则继续到下一行。

    使用if let,了解 optional binding

    if let pathValue = path {
        let baseURL = NSURL(fileURLWithPath: pathValue) //same comment
        AudioServicesCreateSystemSoundID(baseURL, &soundID)
        //play
        AudioServicesPlaySystemSound(soundID)
    } 
    

    现在,如果路径是可选的,则无法到达块并传递到下一行