1

AVAudioPlayer にシングルトンを使用していますが、うまく機能します。

プレーヤーを初期化する前にチェックを追加し、既に何かを再生している場合はプレーヤーを停止したいと考えています。

このコードを追加しました:

SoundPlayer *player = [SoundPlayer sharedInstance];
        if([player isPlaying]){
            [player stop];
 }

しかし、行にEXE_BAD_ACCESSが表示されif([player isPlaying])ます。

2 つの質問:

  1. これがシングルトンで、同じプレーヤーを取得している場合、なぜそれ自体が停止しないのですか?
  2. エラーが発生するのはなぜですか?

完全なコードはこちら

    #import "SoundPlayer.h"

    @implementation SoundPlayer
    @synthesize helpMode;

    static SoundPlayer *sharedInstance = nil;

    + (SoundPlayer *)sharedInstance {
        if (sharedInstance == nil) {
            sharedInstance = [[super allocWithZone:NULL] init];
        }

        return sharedInstance;
    }


    +(BOOL)playSound:(NSURL*)url{

       NSError *error;
        SoundPlayer *player = [SoundPlayer sharedInstance];
            if([player isPlaying]){
                [player stop];
            }

       player = [[SoundPlayer sharedInstance] initWithContentsOfURL:url error:&error];
       [player play];

        if (player == nil){
            NSLog(@"error %@ \n for file %@",[error description],[url path]);   
            return NO;
        }else {
            if (![player helpMode]) {
                 [player play];
            }else{
                NSLog(@"help mode");
            }

        }
         return YES;
    }

    -(void)stopSound{
        if ([self isPlaying]) {
            [self stop];
        }
    }


    @end
4

1 に答える 1

2

これがエラーの原因であるかどうかはわかりませんが、より多くのスペースとコードのフォーマットがあるため、ここでの議論への回答を投稿して私の主張を明確にすることにしました.

いいえ、すべてのメソッドをオーバーライドする必要はありません。すべてを正しく理解していることを確認したかっただけです。私が言っていることのもう1つの部分は、 のようにstopSound{}、self notを使用する必要があるということです

SoundPlayer *player = [SoundPlayer sharedInstance];

コードをこれに変更し、実行して修正されたかどうかを確認し、下にコメントを投稿して結果をお知らせください。

 -(BOOL)playSound:(NSURL*)url{

       NSError *error;
       // SoundPlayer *player = [SoundPlayer sharedInstance];
            if([self isPlaying]){
                [self stop];
            }

       //not sure if this should be self or super (i think super, try both)
       //if you overrided the init then definitely self

       //[self initWithContentsOfURL:url error:&error];
       [super initWithContentsOfURL:url error:&error];


       [self play];

        if (self == nil){
            NSLog(@"error %@ \n for file %@",[error description],[url path]);   
            return NO;
        }else {
            if (![self helpMode]) {
                 [self play];
            }else{
                NSLog(@"help mode");
            }

        }
         return YES;
    }

シングルトンであるため、実際に行うことは、プレイヤーオブジェクトを作成して自己へのポインターを作成することだけです。そうは言っても、代わりに self を「使用する必要がある」という事実以外に、なぜそれがクラッシュするのかわかりません。


+ (SoundPlayer *)sharedInstance {
        if (sharedInstance == nil) {
            sharedInstance = [[super allocWithZone:NULL] init];
        }

        return sharedInstance;
    }

AVAudioPlayerには 2 つのメソッドしかなく、どちらもそうではないため、スーパークラスを完全に初期化していないことがわかります。メソッドをオーバーライドし、このオブジェクトとそのスーパーを url パラメータで初期化する必要があります。.h と .m の両方にを必ず入れてください。また、それが重要かどうかはわかりませんが、そうではないことを試してください。initinitinitWithContentsOfURL:urlinitWithContentsOfURL:urlallocallocWithZone

于 2012-07-16T01:22:10.067 に答える