ios - AVAudioPlayer 并发运行时导致异常

标签 ios objective-c multithreading audio crash

每隔一段时间,当我调用其 play 方法时,AVAudioPlayer 就会崩溃。

我的应用程序是一个游戏,有背景音乐和许多音效。最初,AVAudioPlayer 导致其运行速度非常缓慢。然而,由于它似乎是最简单的声音 API(尤其是对于像我这样的 2D 游戏),我只是决定使用 dispatch_async 同时播放声音。

这带来了相当大的改进,游戏的主线程没有明显的性能损失。但它会导致游戏崩溃。播放时每隔 5 或 10 分钟就会出现异常。

我不明白为什么会发生这种情况。在并发运行之前是否在播放器内部释放了某些内容?或者完全是别的什么?

编辑:

这是我在玩家在游戏中收集硬币时用来播放声音的代码片段。我使用 4 个 AVAudioPlayers,因此声音可以重叠:

if([coinCollectPlayer isPlaying]){
                if([coinCollectPlayer2 isPlaying]){
                    if([coinCollectPlayer3 isPlaying]){
                        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
                            [coinCollectPlayer4 play];});
                    }
                    else dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
                        [coinCollectPlayer3 play];});
                }
                else dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
                    [coinCollectPlayer2 play];});
            }
            else
                dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){[coinCollectPlayer play];});

最佳答案

你偶尔崩溃的原因是这个结构不健全:

if([coinCollectPlayer isPlaying]){
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
        [coinCollectPlayer play];
    });
}

您正在主线程上检查isPlaying。那么,您怎么知道从那时到您在后台线程上说 play 之间,您还没有在后台线程上说过 play 呢?你不知道。可以这样想:

if([coinCollectPlayer isPlaying]){
    // GREAT BIG HOLE HERE YOU CAN DRIVE A TRUCK THROUGH
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 
        [coinCollectPlayer play];
    });
}

您需要使用一致的线程来与音频播放器进行所有通信,并且必须使用锁定/同步来强制一致性,或者必须使用串行队列(DISPATCH_QUEUE_PRIORITY_DEFAULT 不是)。

话虽如此,我认为你所做的事情是错误的。我不认为 AVAudioPlayer 需要或应该在后台线程上使用。

我建议您尝试使用每个 AVAudioPlayer 一次。换句话说,要播放声音,请创建一个 AVAudioPlayer,播放声音,然后将整个东西扔掉。

关于ios - AVAudioPlayer 并发运行时导致异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23146640/

相关文章:

ios - 在 ios 中搜索城市名称

iphone - 完整整数的两倍

iOS 谷歌地图报错

objective-c - 用字符串数组填充 UITableView

ios - 在 Realm 中存储值

ios - 如何在 Flutter 中制作多个 iOS Target?

iphone - 来自 ios webview 的 Cookie

c# - 取消已初始化并在另一个事件处理程序方法中运行的任务

ios - Swift 闭包数组, 'Int' 不是 '()' 的子类型

c++ - 如何为不同的线程找到并保留可用端口?