iOS AVAudioPlayer奇怪的行为

时间:2013-09-16 07:26:37

标签: ios objective-c avaudioplayer

我需要连续播放一系列短(1秒)声音片段。正在为此目的开发一个班级。我正在使用以下代码:

- (void) playClip: (NSData *)clipToPlay
{
    NSError *error = nil;
    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithData: clipToPlay error:&error];
    audioPlayer.numberOfLoops = 0;
    audioPlayer.volume = 1.0f;
    [audioPlayer prepareToPlay];

    if (audioPlayer == nil)
        NSLog(@"%@", [error description]);
    else
        [audioPlayer play];
}

可以看出,clipToPlay包含NSData的声音片段。这段代码的行为很奇怪。如果我在调试器中运行它并在以下行设置断点:

[audioPlayer play];

剪辑按预期播放 - 调试器在线上暂停,当您单步执行时,剪辑可以完美播放。但是,如果我将断点取消,则根本不会发挥作用。

我首先尝试将NSData复制到临时文件,结果完全相同。我还将clipToPlay复制到另一个变量(使用副本,而不仅仅是指针赋值),结果相同(我想也许clipToPlay在某处被破坏了)。我没有记录错误。

我真的坚持为什么暂停调试器的播放方法会导致这种情况发生。有什么建议或想法吗?

1 个答案:

答案 0 :(得分:5)

好的,我发现了这个问题,所以我会回答我自己的问题,所以也许这会在其他时候拯救别人。

问题是AVAudioPlayer在有机会播放声音之前被解除分配。当在断点处停止时,显然有机会在解除分配之前播放声音。

在这个例子中,因为它在它自己的子类中,所以我使audioPlayer成为一个ivar而且我在变量视图控制器中将变量保存为子类的一个ivar。这样就可以在声音未播放时阻止重新分配。

在子类中,我在委托方法中忽略了audioPlayer指针:

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

我不确定这种安排的最终形式是什么,但这至少解释了导致问题的原因。 AVAudioPlayer实例必须在其范围内,直到声音完成播放或ARC将解除分配它。