避免 AVAudioEngineConfigurationChange 通知回调中的死锁

Posted

技术标签:

【中文标题】避免 AVAudioEngineConfigurationChange 通知回调中的死锁【英文标题】:Avoiding deadlock within AVAudioEngineConfigurationChange notification callback 【发布时间】:2022-01-21 18:35:24 【问题描述】:

我有一个 Swift 类,它包含一个 AVAudioEngine 和我的实例,并像这样使用 AVAudioEngineConfigurationChange 通知:

class Demonstration : NSObject 
    
    var engine:AVAudioEngine? = AVAudioEngine()
    
    // ...
    
    override init() 
        super.init()
        
        // ...
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(self.handleEngineConfigChange(_:)),
                                               name: .AVAudioEngineConfigurationChange,
                                               object: nil)
    
    
    @objc func handleEngineConfigChange(_ notification: Notification) 
        
        // what can I wrap this code with in order to make it not dangerous?
        // DispatchQueue.main.sync?
        engine = nil
        
    
    

在docs 中写道:

不要从客户端的通知中取消分配引擎 处理程序。回调发生在内部调度队列上,并且可以 尝试同步关闭引擎时出现死锁。

我什至不知道他们所说的 deallocate 是什么意思——如果它意味着有某种方法,比如 engine.reset() 或 engine.stop()... 或者它是否意味着将引擎设置为 nil...或者它是否只适用于目标 C……我不知道。

无论如何,我只想知道如何设置该方法,以便将来我不必担心破坏。

【问题讨论】:

【参考方案1】:

您可以通过使用DispatchQueue.async(不同步)将其移至运行循环的下一次迭代,该队列是您管理引擎所在的任何队列(可能是主队列)。重要的是您应用从该回调返回的之后的更改。

【讨论】:

谢谢!是否可以包含我的代码的编辑版本以显示正确与错误的方式?

以上是关于避免 AVAudioEngineConfigurationChange 通知回调中的死锁的主要内容,如果未能解决你的问题,请参考以下文章

正确使用@Async,避免踩坑

避免插入失败以避免虚假的自动增量

如何避免两次编写 SQL Server 查询以避免重复?

MYSQL的UPDATE子查询,UPDATE时避免使用子查询

DDoS攻击是啥?应该如何避免?

Delphi 中要避免的组件