是否需要为AVAudioPlayer执行/ catch?

时间:2016-03-29 13:34:08

标签: swift avaudioplayer

我有一个关于AVAudioPlayer所需的do / catch语法的问题。实际上是什么?

让我们根据我看过的教程,看一下代码如何看起来或多或少的一些例子。

1)这里我强制在try语句中展开可选的NSURL。 我的假设是,如果我现在更改mp3名称,它应该调用catch块,但我在try行上遇到nil崩溃,因为avPlayerURL属性为nil。为什么不被抓住?

  do {
        let avPlayer1URL = NSBundle.mainBundle().URLForResource("Test", withExtension: "mp3")
        avPlayer1 = try AVAudioPlayer(contentsOfURL: avPlayer1URL!)
        avPlayer1?.delegate = self
        avPlayer1?.numberOfLoops = -1
        avPlayer1?.prepareToPlay()
    } catch {
        print("Error finding AVAudioPlayer 1 file")
    }

2)我强制直接展开URL属性,结果与1相同。在这种情况下,它有意义,因为永远不会调用try行。所以这个例子我编码的编码很糟糕,但很多教程都是以这种方式向你展示的方式1.

    do {
        let avPlayer1URL = NSBundle.mainBundle().URLForResource("Test", withExtension: "mp3")!
        avPlayer1 = try AVAudioPlayer(contentsOfURL: avPlayer1URL)
        avPlayer1?.delegate = self
        avPlayer1?.numberOfLoops = -1
        avPlayer1?.prepareToPlay()
    } catch {
        print("Error finding AVAudioPlayer 1 file")
    }

3)因此,为了确保NSURL不是零,我使用可选链接。现在的事情是,如果它找不到mp3,它将根本不运行do块,因此不是try行或catch块。因此,不需要此示例中的整个do / catch事物。

     do {
        if let avPlayer1URL = NSBundle.mainBundle().URLForResource("Test", withExtension: "mp3") {
               avPlayer1 = try AVAudioPlayer(contentsOfURL: avPlayer1URL)
               avPlayer1?.delegate = self
               avPlayer1?.numberOfLoops = -1
               avPlayer1?.prepareToPlay()
         }
    } catch {
        print("Error finding AVAudioPlayer 1 file")
    }

所以我的问题基本上都是

1)为什么编译器告诉我使用"尝试" (做/捕获)

2)为什么我在示例1中遇到了崩溃

3)即使我使用可选链接来确保mp3存在,AVAudioPlayer仍会抛出错误吗?

1 个答案:

答案 0 :(得分:3)

  

我在try行上遇到了nil崩溃,因为avPlayerURL属性为nil。为什么不被抓住?

使用Do-Catch的Swift错误处理仅捕获错误,它不会捕获异常

展开nil可选导致异常,它不会引发错误。

因此,设计问题不是catch

对AVAudioPlayer使用catch意味着如果AVAudioPlayer 本身引发错误,则会捕获此错误。

要显示抛出错误的内容,一种不错的方法是将错误消息向下传播到NSError,如下所示:

do {
    // ...
} catch let error as NSError {
    print(error.debugDescription)
}

例如,假设您有一个MP3文件,但此文件的数据已损坏且无法播放。

您将在第三个示例中检查文件是否存在,并且它会认为文件正常 - 但播放器会抛出错误,因为它无法启用阅读文件的内容。