你需要一个属性或伊娃的原因是它提供了强有力的参考。当使用ARC时,任何没有强指针的对象都是公平的游戏,而且事实上这就是你所看到的。
你也是正确的,一个AVAudioPlayer
强指针将只允许一次引用一个音频播放器。
如果您选择继续使用AVAudioPlayer
的解决方案是使用某种集合对象来保存所有播放器实例的强引用。你可以使用一个NSMutableArray
如下所示:
编辑我调整了代码稍微使播放的声音方法需要一个NSString
soundName
参数。
@synthesize audioPlayers = _audioPlayers;
-(NSMutableArray *)audioPlayers{
if (!_audioPlayers){
_audioPlayers = [[NSMutableArray alloc] init];
}
return _audioPlayers;
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
[self.audioPlayers removeObject:player];
}
-(void)playSoundNamed:(NSString *)soundName{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:soundName
ofType:@"wav"]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
if (audioPlayer){
[audioPlayer setDelegate:self];
[audioPlayer prepareToPlay];
[audioPlayer play];
[self.audioPlayers addObject:audioPlayer];
}
}
通常的AVAudioPlayer
是矫枉过正一个声音效果/音板应用。为了快速声“滴”,你可能会发现音频工具箱框架,outlined in my answer to this question.
From looking at the System Sound class reference, it seems like you can only play one sound at a time.
它只能起到一个SystemSoundID
在同一时间。例如,如果你有soundOne和soundTwo。当soundTwo正在播放时,您可以播放soundOne,但一次不能播放一种声音的多个实例。
What's the best way to be able to play sounds that can overlap while still being efficient with the amount of code and memory?
最好是意见。
如果你需要两个相同声音同时播放的实例,那么我会说在这个答案中发布的代码将是代码使用。由于相同声音的每个重叠实例都需要创建新资源,因此使用audioPlayerDidFinishPlaying:
这样的代码更易于管理(内存可以很容易地被回收)。
如果相同声音的重叠实例不是交易断路器,那么我认为只需使用AudioServicesCreateSystemSoundID()
来创建每个声音的一个实例就更有效率。
我绝对不会试图管理每个按下按钮的创建和处理SystemSoundID
s。这会匆匆出错。在这种情况下,AVAudioPlayer
仅仅是可维护性的明显赢家。
从查看System Sound类参考,看起来您一次只能播放一个声音。能够播放可重叠的声音的最佳方式是什么,而对代码和内存的数量仍然有效? – robertfiorentino
@fiorgodx我编辑了我的答案以回应您的评论。 – NJones
帮助我解决了当前正在播放的播放器的停止问题,并在启动另一个播放器时释放它(不停止播放按钮)。现在,内存使用并不是天空飞扬,它只能作为唯一一个音频播放器的例子。谢谢 –