AVAudioPlayer在并发运行时导致异常

时间:2014-04-18 02:50:45

标签: ios objective-c multithreading audio crash

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

我的应用程序是一款带有背景音乐和许多音效的游戏。最初,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];});

1 个答案:

答案 0 :(得分:0)

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

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,播放声音,然后抛弃整个声音。