这是我的Swift 2.1代码段。发生的错误显示在错误出现点的注释中。
错误显示在调试面板中,应用程序崩溃。该应用程序永远不会在捕获中打印该行,也不会按预期正常返回。
let audioFileURL = receivedAudio.filePathURL
guard let audioFile = try? AVAudioFile(forReading: audioFileURL) else {
print("file setup failed")
return
}
let audioFileFrameCount = AVAudioFrameCount(audioFile.length)
audioFileBuffer = AVAudioPCMBuffer(PCMFormat: audioFile.fileFormat, frameCapacity: audioFileFrameCount)
do {
// ERROR: AVAudioFile.mm:263: -[AVAudioFile readIntoBuffer:frameCount:error:]: error -50
// Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio', reason: 'error -50'
// -50 = Core Audio: bad param
try audioFile.readIntoBuffer(audioFileBuffer)
}
catch {
print("unable to load sound file into buffer")
return
}
从我看过的所有内容来看,我的do / try / catch格式应该是正确的。
audioFile.readIntoBuffer
返回void
并且有关键字throws
。
然而,捕获永远不会被执行。
我错过了什么?
更新:From Apple's documentation on AVAudioFile
有关:
func readIntoBuffer(_ buffer: AVAudioPCMBuffer) throws
在讨论:
下处理SWIFT中的错误:
在Swift中,此API作为初始化程序导入,并使用throws关键字进行标记,以指示在发生故障时会引发错误。
在try表达式中调用此方法并处理do语句的catch子句中的任何错误,如Swift编程语言中的错误处理(Swift 2.1)和使用Swift与Cocoa和Objective-C中的错误处理中所述(斯威夫特2.1)。
来自The Swift Programming Language (Swift 2.1): Error Handline
请注意
Swift中的错误处理类似于其他语言中的异常处理,使用了try,catch和throw关键字。与许多语言中的异常处理不同 - 包括Swift中的Objective-C-error处理不涉及展开调用堆栈,这可能是计算上昂贵的过程。因此,throw语句的性能特征与return语句的性能特征相当。
最后,来自同一份文件:
使用Do-Catch处理错误
使用do-catch语句通过运行代码块来处理错误。如果do子句中的代码抛出错误,则会与catch子句匹配,以确定哪一个可以处理错误。
我没有必要编写并抛出我自己的错误/异常才能被捕获。我也应该能够捕捉到Swift的例外情况。
答案 0 :(得分:4)
do - catch
组合没问题。这个问题只是一个无法捕获的问题 - 因此永远不会进入catch
阻止。
如果问题是可捕获的(通过Swift的throws
功能定义和处理),则catch
块将被执行。
一些语义:关于术语错误和异常之间的差异存在长期争论。
一些开发人员认为这两个术语是截然不同的。在这种情况下,术语错误表示旨在处理的问题。斯威夫特的throws
行动适合这里。在这种情况下,do - catch
组合将允许捕获问题。
对于这些开发人员来说,异常代表了一个意外的,通常是致命的问题,无法捕获和处理。 (一般来说,即使你能抓住它,你也无法处理它。)
其他人认为这两个术语是等同的和可互换的,无论是否可以捕获有关问题。 (Apple的文档似乎遵循这一理念。)
(更新以关注答案而不是语义。)
答案 1 :(得分:2)
catch
只会捕获显式抛出的错误。它永远不会捕获异常。
你在这里看到的是AVAudioFile SDK中发生的异常,而不是Swift错误,所以它没有被捕获:
错误:AVAudioFile.mm:263: - [AVAudioFile readIntoBuffer:frameCount:error:]:error -50
因未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:'error -50'
-50 =核心音频:坏参数
在Swift的上下文中,“error”表示函数抛出的错误,没有别的。你的功能与否无关紧要。
斯威夫特的例外并没有被抓住。例如,它与Java完全不同。在Swift中,错误!=异常,它们是两个非常不同的东西。
我理解你的意见“它应该适用于两者”但事实并非如此。如果需要,您可以将此视为使用关键字“catch”的语义情况,因为它与其他语言的关键字相同,但行为却截然不同;它很像,但它不一样。
对于AVAudioFile的异常,我没有解决方案 - 也许这是这个SDK中的错误?或者它还没有正确绑定到Swift和投掷系统。在这种情况下,如果没有其他人有解决方案,请不要犹豫向Apple报告错误。
答案 2 :(得分:0)
见这个例子
struct E: ErrorType{}
func foo(i: Int) throws {
if i == 0 {
throw E()
}
print(10 / (i - 1))
}
do {
//try foo(1) // if you uncomment this line, the execution
// will crash, even though the function is declared
// as throwing and you use proper calling style (do / try / catch pattern)
try foo(0)
} catch {
print("error: ", error) // error: E()
}