AVAudioEngine.start() 中的崩溃,即使它包含在 do/catch 中
Posted
技术标签:
【中文标题】AVAudioEngine.start() 中的崩溃,即使它包含在 do/catch 中【英文标题】:Crash in AVAudioEngine.start() even though it's wrapped in do/catch 【发布时间】:2016-03-19 23:50:07 【问题描述】:我有以下代码来(重新)启动AVAudioEngine
连接到AVAudioEngineConfigurationChangeNotification
:
do
try self.engine.start()
catch
DDLogError("could not start sound engine")
self.soundEnabled = false
return
self.engine 被定义为
private let engine = AVAudioEngine()
但是,我经常通过 Crashlytics 收到崩溃报告
致命异常:com.apple.coreaudio.avfaudio 错误 561015905
在包含try self.engine.start()
的行上。
561015905 是AVAudiosessionErrorCodeCannotStartPlaying
,据我了解,这应该是NSError
错误代码,而不是异常,它应该被我上面代码中的空白catch
捕获。尽管如此,该应用程序似乎在那一点上崩溃了。我错过了什么?
我知道在某些情况下,应用程序在后台唤醒时可能会发生此错误,只要我能以某种方式捕捉到它的发生,我就可以接受,就像我认为 do/catch
可以做到的那样。
【问题讨论】:
我收到了类似的错误。你知道为什么会这样吗? 没有。我已经向 Apple 提交了错误报告,但尚未收到回复。同时我停止使用AVAudioEngine
。
@Mike 对此有何更新?您是否找到了比 sleep() 更好的解决方法?你有没有收到苹果的消息?从外观上看,这在 iOS 11 中仍然是一个问题。
正如我已经说过的,由于这个错误,我们已经停止使用AVAudioEngine
。此后,Apple 要求我们使用较新的 iOS 版本重现该错误(并在新 SDK 版本发布时发送自动消息以打开报告),但由于我们不再对该问题感兴趣,因此我们没有这样做。这意味着如果您仍然关心,您可能应该打开自己的错误报告。抱歉,我无法提供更多帮助,祝您好运。如果您愿意,我很乐意收到回复!
【参考方案1】:
Xcode 版本 9.2 (9C40b) + Swift 4:我知道这个问题有点老了,但是,我遇到了与 audioEngine.start()
相同的崩溃问题,即使在 do/try/catch 中并且还收到了以下来自崩溃分析:
致命异常:com.apple.coreaudio.avfaudio 错误 561015905
S1LENT WARRIOR 的 sleep(1) “hack”在某些情况下有效,但不是全部(特别是 AVAudioEngineConfigurationChangeNotification 选择器)。
最后,我使用了 Obj-C 异常处理来真正捕获错误,因此不会发生崩溃,来自 freytag 的这篇非常有用的帖子(非常感谢!):
Catching NSException in Swift
现在,在实现了 ObjC .h 和 .m 文件以及桥接头之后,我会这样做:
do
try ObjC.catchException
try! self.audioEngine.start()
catch
print("An error occurred: \(error)")
您可以通过搞砸引擎初始化来测试这一点(例如,不要 .attach 或 .connect 任何东西)并且不会崩溃......只有:
2018-01-06 10:01:48.890801+0700 XXXXXX[16389:3367770] [avae] AVAEInternal.h:70:_AVAE_Check: 所需条件为 false: [AVAudioEngineGraph.mm:1209:Initialize: (inputNode != nullptr || outputNode != nullptr)] 发生错误:Error Domain=com.apple.coreaudio.avfaudio Code=0 "(null)"
确保在使用之前检查 audioEngine 是否正在运行,例如:
func play(soundName: String)
if !audioEngine.isRunning
return
// play sound
好的,所以你没有声音,但这是一个“优雅的失败”。
在 Swift 中您无法正确捕获异常似乎很荒谬,如果您要制作一些不可捕获的异常,那么至少提供一种首先进行测试的方法,例如 audioEngine.areYouConfiguredProperly()
。哦,等一下,有这个方法(在 Obj-C 中)[AVAudioEngine startAndReturnError:]
,但有人决定用 startEngine()
函数包装它,并取消所有有用的功能...... doh。
【讨论】:
【参考方案2】:我在处理AVAudioSessionInterruption
通知时遇到了同样的错误。
就我而言,当我在中断结束后尝试启动 AVAudioEngine
时出现错误。
经过一段时间的详细测试和调试,我注意到如果我在audioEngine.prepare()
或audioEngine.start()
之前引入debugger breakpoint
,应用程序不会崩溃。
所以我在audioEngine.start()
之前添加了sleep(1)
,我的应用程序停止崩溃!
我知道这不是一个非常优雅的解决方案,但仍然希望这对其他人有帮助!
【讨论】:
以上是关于AVAudioEngine.start() 中的崩溃,即使它包含在 do/catch 中的主要内容,如果未能解决你的问题,请参考以下文章