2

我正在尝试使用 AVAudioPlayer 快速连续播放一些声音。当我不那么频繁地调用声音播放函数以便在再次调用该函数之前完全播放声音时,应用程序运行良好。但是,如果我快速连续调用该函数(以便在播放之前的声音时播放声音),应用程序最终会在调用该函数约 20 次后崩溃,并显示消息“EXC_BAD_ACCESS”。这是该函数的代码:

NSString *nsWavPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:wavFileName];

AVAudioPlayer* theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:nsWavPath] error:NULL];
theAudio.delegate = self;

[theAudio play];

正如另一个线程中提到的,我实现了以下委托函数:

- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    if(!flag)
        NSLog(@"audio did NOT finish successfully\n");
    [player release];
}

但是在大约 20 次快速调用该函数后,该应用程序仍然崩溃。知道我做错了什么吗?

4

2 回答 2

1

我找到了解决这个问题的更好方法。您只需要激活/停用您的 AVAudioSession。

例如:在您的 viewDidLoad 方法中输入:

NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive:YES error:&activationError];

然后,您可以使用以下任何方法播放声音:

... some awesome code ...
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
[self.audioPlayer setDelegate:self];
[self.audioPlayer setVolume: 0.7f];
[self.audioPlayer setNumberOfLoops:0];
if ([self.audioPlayer prepareToPlay]) {
    [self.audioPlayer play];            
}
....

最后,(无论声音是否播放完毕),当你完成声音后,只需执行以下操作:

// I've made it on the view's callback
- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self.audioPlayer stop];
    [self setAudioPlayer:nil];
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive:NO
                                         error:&activationError];
    .... etc, etc...
}

仅此而已:) 您的应用程序将永远不会因 EXC_BAD_ACCESS 再次崩溃。

希望这对您有所帮助并避免这种 hacky [自我保留] / [自我释放]

来自 Apple 的音频会话编程指南: https ://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/ConfiguringanAudioSession/ConfiguringanAudioSession.html

于 2012-08-21T04:48:45.913 回答
1

首先:确保您没有再次尝试播放已经通过“[player release]; 如果您是”发布的声音,您将立即收到该错误消息。一旦您释放与特定声音关联的播放器,您将无法再次播放该文件,就像您在此处显示的那样。尝试注释掉那行代码,看看它是否仍然发生。

我还遇到了一个问题,AVAudioPlayer每次创建一个新的时分配 32kb player,如果你有足够的声音,你可能会用完内存并崩溃。我非常怀疑这是您的问题,因为它通常不会抛出该错误代码。

EXC_BAD_ACCESSplayer对于我在此论坛上看到的大多数情况,通常是尝试访问不再存在的指针(例如您的对象)

于 2010-06-16T03:17:08.407 回答