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 中的主要内容,如果未能解决你的问题,请参考以下文章

WebCore bmalloc :: IsoAllocator在iOS 11.3中崩溃

Xcode7 的两个小坑

一个全局变量引起的DLL崩溃

数值线性代数实验-共轭梯度法

西安赛打铁队检讨书

iPhone sdk 以编程方式读取崩溃文件?