gpt4 book ai didi

objective-c - AVAudioplayer 或 delegate 过早分配的问题

转载 作者:行者123 更新时间:2023-12-03 20:16:39 25 4
gpt4 key购买 nike

我正在为 children 制作一个计数游戏。一开始, child 被要求找到一些元素,例如:“你能找到五辆自行车吗”。这些都是由单独的声音数组和句子的一部分随机组合在一起的:“你能找到”+“5”+“自行车”=三个单独的 mp3。当 child 开始点击这些元素时,它们就会消失,并且声音开始计数。 “1”、“2”、“3”、“4”、“5”,最后是“自行车”。

我使用audioPlayerDidFinishPlaying:委托(delegate)方法将声音组合在一起,并且大多数情况下效果很好。但有时应用程序会崩溃,并出现“bad_access”错误。使用 NSZombie 后我得到: -[AVAudioPlayer PerformSelector:withObject:]: message sent to deallocated instance

我认为这是因为音频播放器本身或委托(delegate)被过早释放。

我总是使用这个函数来播放声音:

-(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");

}

这是委托(delegate)(它根据声音完成的内容执行不同的操作):

-(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 自动发布来得太早了,尽管声音还没有完成。我尝试过不自动释放,而是在委托(delegate)函数中显式释放。但问题是声音并不总是播放到最后(当 child 在声音读完之前找到新项目时)...

你们中的任何人都可以阐明这一点吗?我将不胜感激!

最佳答案

您需要保留 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");
}

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

关于objective-c - AVAudioplayer 或 delegate 过早分配的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3582676/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com