我有一个关于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仍会抛出错误吗?
答案 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文件,但此文件的数据已损坏且无法播放。
您将在第三个示例中检查文件是否存在,并且它会认为文件正常 - 但播放器会抛出错误,因为它无法启用阅读文件的内容。