AVAudioplayer singleton在isPlaying检查时崩溃

时间:2012-07-15 15:09:24

标签: ios singleton avaudioplayer

我在AVAudioPlayer上使用单例,效果很好。

我希望在初始化播放器之前添加一个检查,并在播放器已播放的情况下停止播放。

我添加了这段代码:

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

但是它在if([player isPlaying])行上给了我一个EXE_BAD_ACCESS。

2个问题:

  1. 如果这是一个单身人士并且我回到了同一个玩家那么为什么它不会自行停止?
  2. 为什么我收到错误?
  3. 这是完整的代码

        #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
    

1 个答案:

答案 0 :(得分:2)

我不确定这是否是导致错误的原因,但我想我会在这里的讨论中发布我的回复以使我的观点更清楚,因为我有更多的空间和代码格式。

不,你不必覆盖所有的方法,我只是要求确保我理解一切正确。 我要说的另一件就是像stopSound{}一样,你应该使用自我而不是

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;
    }

请参阅here AVAudioPlayer只有2个init方法,而且都不只是init因此您没有完全初始化超类。您需要覆盖initWithContentsOfURL:url方法并使用url参数初始化此对象及其super。只需确保将initWithContentsOfURL:url放在.h和.m中。如果重要的话也请点击,但只是alloc而不是allocWithZone