プロパティまたはivarが必要な理由は、それが提供する強力な参照のためです。ARCを使用する場合、それへの強力なポインターのないオブジェクトは、割り当て解除のための公正なゲームであり、実際、それがあなたが見ているものです。
AVAudioPlayerまた、強力なポインターでは、一度に1つのオーディオプレーヤーしか参照できないということも正しいです。
引き続き使用する場合の解決策は、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効果音/サウンドボードアプリケーションにとってはやり過ぎです。この質問への私の回答で概説されているように、すばやく音を「落とす」には、オーディオツールボックスフレームワークが見つかる可能性があります。
システムサウンドクラスリファレンスを見ると、一度に再生できるサウンドは1つだけのようです。
一度に1つしか再生できませんSystemSoundID。たとえば、soundOneとsoundTwoがある場合。soundTwoの再生中にsoundOneを再生できますが、一度にどちらかのサウンドの複数のインスタンスを再生することはできません。
コードとメモリの量を効率的に保ちながら、オーバーラップできるサウンドを再生できるようにするための最良の方法は何ですか?
最高は意見です。
同じサウンドの2つのインスタンスを同時に再生する必要がある場合は、この回答に記載されているコードが使用するコードになると思います。同じサウンドの重複するインスタンスごとに新しいリソースを作成する必要があるため、このようなコードaudioPlayerDidFinishPlaying:ははるかに管理しやすくなります(メモリは簡単に再利用できます)。
AudioServicesCreateSystemSoundID()同じサウンドの重複するインスタンスが問題にならない場合は、各サウンドのインスタンスを1つ作成するために使用する方が効率的だと思います。
SystemSoundIDボタンを押すたびにの作成と破棄を管理しようとは絶対にしません。それは急いでうまくいかないでしょう。その場合AVAudioPlayer、保守性だけで明らかに勝者となります。