背景线程上的AVAudioPlayer

时间:2017-06-22 16:11:47

标签: objective-c multithreading macos audio sprite-kit

我对使用后台线程知之甚少,但这似乎按照我需要的方式播放我的声音如下:

1)即使声音重叠,我也需要这种非常短的声音效果才能重复播放。 2)我需要按时完美播放声音。 3)我需要加载声音,以免因口吃而影响屏幕上的图形。

我目前只是用一种声音尝试这种方法,但如果成功,我会将其推广到需要相同处理的其他声音效果。 我的问题是:我是否正确使用后台线程?会有任何类型的内存泄漏吗?

以下是代码:

-(void) playAudio {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        NSString *path = [NSString stringWithFormat:@"%@/metronome.mp3", [[NSBundle mainBundle] resourcePath]];
        NSURL *metronomeSound = [NSURL fileURLWithPath:path];
        _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:metronomeSound error:nil];
        [_audioPlayer prepareToPlay];
        [_audioPlayer play];
    });
}

//handles collision detection
-(void) didBeginContact:(SKPhysicsContact *)contact {
    uint32_t categoryA = contact.bodyA.categoryBitMask;
    uint32_t categoryB = contact.bodyB.categoryBitMask;

    if (categoryA == kLineCategory || categoryB == kLineCategory) {
        NSLog(@"line contact");
        [self playAudio];
    }
}

1 个答案:

答案 0 :(得分:2)

我使用AVAudioPlayer并异步使用它并在后台线程中使用它没有任何问题,并且据我所知没有泄漏。但是,我已经实现了一个处理所有分配的单例类,并保留了一个AVAudioPlayer实例数组,这些实例也根据需要异步播放。如果需要重复播放声音,则应在每次播放时分配AVAudioPlayer实例。在这种情况下,延迟可以忽略不计,您甚至可以同时播放相同的声音。

关于您的策略,我认为它需要一些改进,特别是如果您想要防止任何延迟。主要问题是始终从磁盘读取,这是所有操作中最慢的操作和限制步骤。

因此,我还会实现一个AVAudioPlayers数组,每个AVAudioPlayers都已初始化以播放特定声音,特别是如果经常重复播放此声音。如果内存开始增长,你可以删除那些从阵列中播放次数较少的玩家实例,并在几秒前重新加载它们,如果你能分辨出哪些需要它们。

还有一件事......不要忘记锁定和解锁数组,如果要从多个线程访问它或者更好的话,创建一个GCD队列来处理对数组的所有访问。