【发布时间】:2016-05-21 18:11:48
【问题描述】:
这是我的 Swift 2.1 代码 sn-p。正在发生的错误会显示在错误出现点的 cmets 中。
调试面板中出现错误,应用程序崩溃。应用从不打印 catch 中的行,也不会像预期的那样优雅地返回。
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。
然而,catch 永远不会被执行。
我错过了什么?
更新: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 关键字。与许多语言(包括 Objective-C)中的异常处理不同,Swift 中的错误处理不涉及展开调用堆栈,这是一个计算成本很高的过程。因此,throw 语句的性能特征与 return 语句的性能特征相当。
最后,来自同一个文档:
使用 Do-Catch 处理错误
您使用 do-catch 语句通过运行代码块来处理错误。如果 do 子句中的代码抛出错误,则将其与 catch 子句进行匹配,以确定其中哪一个可以处理错误。
我不必编写和抛出我自己的错误/异常来捕获它们。我应该也能捕捉到 Swift 的异常。
【问题讨论】:
-
catch只会捕获明确抛出的错误。它不会捕获异常。您在这里似乎遇到的是 AVAudioFile SDK 中发生的异常,而不是 Swift 错误,因此没有被捕获。 -
我添加了一个更新,其中包括可互换使用术语 errors 和 exceptions 的 Apple 文档:Error handling in Swift 类似于其他语言中的 exception 处理,使用 try、catch 和 throw 关键字。 它应该适用于两者!
-
在 Swift 的上下文中,“错误”是指一个函数抛出的错误,不管是不是你的,仅此而已。 永远不会捕获 Swift 中的异常。例如,它与 Java 完全不同。我理解您的观点,即“它应该适用于两者”,但事实并非如此。如果需要,您可以使用关键字“catch”将其视为语义情况,因为它与其他语言的关键字相同,但行为却截然不同。它类似,但不是。 :)
-
鉴于编程指南中的措辞,您可以理解我的困惑,@Eric D.。我会进一步研究。
-
@Johannes:我没有找到原因。该错误意味着“错误的参数”,但可能是由甚至与该代码行无关的其他事情引起的。相反,我使用了一种不同的技术来处理音频。该项目采用 Swift 2.1,位于 GitHub,如果您想看看。