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 文件,但该文件的数据已损坏且无法播放。
您将像第三个示例一样检查文件是否存在,它会认为文件正常 - 但随后 播放器 将抛出错误,因为它不会能够读取文件的内容。
我对 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 文件,但该文件的数据已损坏且无法播放。
您将像第三个示例一样检查文件是否存在,它会认为文件正常 - 但随后 播放器 将抛出错误,因为它不会能够读取文件的内容。