0

少し整理が必要なコードをいくつか継承しました。このアプリにはいくつかのコア サウンドがあり、現在、AVAudioPlayerさまざまな にアタッチされた多数のインスタンスがViewControllerすべて同じ少数のサウンドを再生しています。

リファクタリングの演習の一環として、私は というシングルトン クラスを実装することにしましたSoundController。このクラスには、AVAudioPlayer再生が必要なサウンドごとに 1 つが含まれ、それぞれViewControllerが独自のインスタンスを作成する代わりに、1 つだけを簡単に利用できます。

[[SoundController controller].majorFunctionSound playAtTime:0];

もう 1 つの重要な点は、遅延を最小限に抑えるために、使用する前にすべてのサウンドに対して prepareToPlay: が呼び出されていることを確認することです。ほんの一握りのサウンドしかなく、それらはすべてユーザー セッション中に使用される可能性が高いため、SoundController が最初にインスタンス化されるときにすべてのサウンドを (バックグラウンド スレッドで) プリロードすることは理にかなっています。init メソッドには、次のようなものがあります。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, nil, ^(void)          
{
NSURL *soundURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/MAJOR FUNCTION.m4a", [[NSBundle mainBundle] resourcePath]]];
_majorAudioSound = [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil];
[_majorAudioSound  prepareToPlay];
});

majorAudioSoundは(readonly, strong)@synthesize majorAudioSound = _majorAudioSound.

私の懸念は、同時実行性の点でこれがどれほどうまく機能しないか (またはうまく機能するか) と、コードを改善するために何ができるかです。具体的には、これを行うと:

[[SoundController controller].majorFunctionSound playAtTime:0];

バックグラウンドの初期化ブロックがまだ完了しているかどうかによっては、majorFunctionSound が適切に開始されない可能性が明らかにあります。プロパティが返さnilれ、サウンドが再生されないという最悪の事態が発生する可能性はありますか?

他にどのような問題が考えられますか? AVAudioPlayer が適切に設定されていることを常に確認する方法はありますか?

4

1 に答える 1

1

まず、クラスのインスタンスを 1 つだけ持つつもりであるという理由だけで、クラスをシングルトンにする必要があるかどうかについて考え直してください。もちろん、それは1つの方法ですが、初期化の問題は、シングルトンクラスを使用することにしたという事実から継承されていると思います。

SoundManager というクラスがあり、それをシングルトン クラスにしたとします。

アプリ内の任意の場所で SoundManager のインスタンスを要求する場合、返されたインスタンスはすぐに使用できる状態になっていると想定する必要があります。SoundManager 内に非同期の init メソッドがある場合、設計上の問題があります。Singleton を要求するときに、それが初めてか初期化されていないかを知る必要がないからです。

SoundManager には初期化が必要なので、Singleton にする代わりに、アプリケーション フローを処理するある種の基本クラスで、SoundManager のインスタンスをアプリに持たせます。AppDelegate に唯一無二の SoundManager をインスタンス化させるか、ApplicationController というクラスを作成するか、初期化時にアプリに必要なすべてのものをロードするクラスを作成します。次に、参照を渡すか、ApplicationController をシングルトンにすることで、このコントローラー クラスを介して SoundManager インスタンスに到達できます。もちろん、SoundManager がシングルトンの場合でも、起動時に確実に初期化する限り、これは機能しますが、シングルトン クラスはできるだけ少なくすることを好みます。

サウンドがロードされているかどうかについての質問です。

ユーザーにアプリの使用を開始させる前に、すべてのサウンドをロードすることをお勧めします。その間、ロード画面やプログレスバーなどをユーザーに表示したり、必要に応じてサウンドや音楽を再生したりできます。構造の例を次に示します。

  • 最初からfalseである「ロード済み」プロパティを持つSoundManagerというクラスを作成します
  • SoundManager をインスタンス化する ApplicationController というクラスと、TextureManager や LocationManager などの他の便利なクラスを作成します。
  • アプリが起動したら、ApplicationController をインスタンス化します。これにより、SoundManager がインスタンス化されます。
  • ロード画面を表示する
  • まずSoundManagerに「読み込み音」を読み込ませ、読み込まれたら再生を開始する
  • サウンドの読み込みが完了したら、"loaded" プロパティを true に設定します。
  • ApplicationController がすべてをロードしたら、ロード画面をフェードアウトして、ユーザーがアプリの使用を開始できるようにします。

サウンドが読み込まれる前でもユーザーにアプリの使用を開始させる必要がある場合は、「loaded」というプロパティを使用することで、同じアプローチを引き続き使用できます。このプロパティの処理を同期させておくことを忘れないでください。

于 2012-08-13T09:38:31.637 に答える