我正在为孩子们做一个计数游戏。开始时,要求孩子找到一些物品,例如:“你能找到五辆自行车吗”。这些都是从声音的单独数组中随机组合在一起的,句子的一部分为:“您可以找到” +“ 5” +“自行车” =三个单独的mp3。当孩子开始单击这些项目时,它们消失了,声音逐渐增加。 “ 1”,“ 2”,“ 3”,“ 4”,“ 5”,最后是“自行车”。

我使用audioPlayerDidFinishPlaying:委托方法将声音放在一起,并且大多数情况下效果很好。但是有时应用程序崩溃,并出现“ bad_access”错误。使用NSZombie之后,我得到:-[AVAudioPlayer performSelector:withObject:]:消息发送到已释放实例

我认为这是因为音频播放器本身或代表过早释放。

我总是使用此功能来播放声音:

-(void)spillVoice:(NSString*) filnavn{
NSString *audioFilePath=[[NSBundle mainBundle] pathForResource:filnavn ofType:@"mp3"];
NSURL *audioFileURL=[NSURL fileURLWithPath:audioFilePath];
self.voicespiller=[[[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil] autorelease];
self.voicespiller.delegate=self;
[self.voicespiller prepareToPlay];
[self.voicespiller play];
NSLog(@"spiller lyden");


}

这是代表(它根据完成的声音执行不同的操作):

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer*)which_player successfully:(BOOL)the_flag{
NSLog(@"ny lyd?");
[self.jenteBilde stopAnimating];
if(self.etterLyd==@"ingenting"){
    NSLog(@"ingenting");
}
else if(self.etterLyd==@"lesobjekt"){
    NSLog(@"lesobjekt");
    self.etterLyd=@"ros";
    [self spillVoice:[self.objektNedArray objectAtIndex: [self.objektnr intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introtall"){
    NSLog(@"introtall");
    self.etterLyd=@"introobjekt";
    [self spillVoice:[self.telleOppArray objectAtIndex: [self.tilfeldig intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"introobjekt"){
    NSLog(@"introobjekt");
    self.etterLyd=@"ingenting";
    [self spillVoice:[self.objektOppArray objectAtIndex: [self.objektnr intValue]]];
    [self.jenteBilde startAnimating];
}
else if(self.etterLyd==@"ros"){
    NSLog(@"ros");
    NSMutableArray *rosArray=[[NSMutableArray alloc] initWithObjects:@"TT_flott",@"TT_bravo",@"TT_fint",@"TT_du_er_kjempeflink",@"TT_hurra",@"TT_helt_riktig",nil];
    int result=(arc4random() % (rosArray.count));
    self.etterLyd=@"ingenting";
    [self spillVoice:[rosArray objectAtIndex: result]];
    [self.jenteBilde startAnimating];
}


}

在我看来,即使音频尚未完成,AVaudioplayers的自动发行也为时过早。我试过不自动释放,而是在委托函数中显式释放。但是问题是声音并不会一直播放到最后(当孩子在声音读完之前找到新的东西时)...

你们中的任何一个都可以阐明这一点吗?我会很感激!

最佳答案

完成之前,您需要保留AVAudioPlayer。最简单的方法是将voicespiller属性设置为保留属性,并将实现更改为以下内容:

-(void)spillVoice:(NSString*)filnavn {
    // stop any previous player
    [self.voicespiller stop];

    NSString *audioFilePath=[[NSBundle mainBundle] pathForResource:filnavn ofType:@"mp3"];
    NSURL *audioFileURL=[NSURL fileURLWithPath:audioFilePath];

    [self setVoicespiller:[[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil] autorelease];
    self.voicespiller.delegate=self;
    [self.voicespiller prepareToPlay];
    [self.voicespiller play];
    NSLog(@"spiller lyden");
}


当您调用属性的更改器([self setVoicespiller:...])时,将释放前一个播放器,并设置新的播放器。然后只需确保在您的dealloc方法中调用[voicespiller release]

08-18 09:30