AVAudioPlayer 不需要 do/catch 吗?

Is do/catch for AVAudioPlayer unnecessary?

我对 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) 为什么编译器告诉我使用 "try" (do/catch)

2) 为什么我会在示例 1 中崩溃

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

I get a nil crash on the try line because the avPlayerURL property is nil. Why is it not getting catched?

Swift 的 Do-Catch 错误处理只捕获 错误 ,它不捕获 异常 .

解包一个 nil Optional 会导致异常,它不会抛出错误。

因此,根据设计,此问题不会被 catch 捕获。

Using catch for AVAudioPlayer 意味着如果AVAudioPlayer 自身抛出一个错误,这个错误会被捕获。

要显示抛出错误的内容,一个很好的方法是将错误消息向下转换为 NSError,如下所示:

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

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

您将像第三个示例一样检查文件是否存在,它会认为文件正常 - 但随后 播放器 将抛出错误,因为它不会能够读取文件的内容。