AVAudioPlayer立即停止使用ARC播放

时间:2011-10-07 21:05:55

标签: objective-c ios avfoundation avaudioplayer automatic-ref-counting

我试图通过AVAudioPlayer播放MP3,我觉得这很简单。不幸的是,它并没有完全奏效。以下是我所做的一切:

  • 为了测试,我创建了一个新的iOS应用程序(Single 查看)在Xcode。
  • 我将AVFoundation框架添加到项目中,并将#import <AVFoundation/AVFoundation.h>添加到ViewController.m

  • 我在应用'文档'文件夹中添加了一个MP3文件。

  • 我将ViewControllers viewDidLoad:更改为以下内容:

代码:

- (void)viewDidLoad
{
    [super viewDidLoad];        

    NSString* recorderFilePath = [NSString stringWithFormat:@"%@/MySound.mp3", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]];    

    AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:recorderFilePath] error:nil];
    audioPlayer.numberOfLoops = 1;

    [audioPlayer play];

    //[NSThread sleepForTimeInterval:20];
}

不幸的是,音频在开始播放后显然会立即停止。如果我取消注释sleepForTimeInterval它播放20秒并在之后停止。只有在使用ARC进行编译时才会出现此问题,否则,它会完美无缺地运行。

3 个答案:

答案 0 :(得分:7)

问题在于,在使用ARC进行编译时,您需要确保保留对要保持活动的实例的引用,因为编译器将通过插入{{自动修复“不平衡”alloc。 1}}调用(至少在概念上,阅读Mikes Ash blog post for more details)。您可以通过将实例分配给属性或实例变量来解决此问题。

在Phlibbo案例中,代码将转换为:

release

- (void)viewDidLoad { [super viewDidLoad]; NSString* recorderFilePath = [NSString stringWithFormat:@"%@/MySound.mp3", [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]]; AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:recorderFilePath] error:nil]; audioPlayer.numberOfLoops = 1; [audioPlayer play]; [audioPlayer release]; // inserted by ARC } 它会立即停止播放,因为在没有参考时会被取消分配。

我自己没有使用ARC,只是简单地阅读了它。如果您对此有更多了解,请对我的答案发表评论,我会更新更多信息。

更多ARC信息:
Transitioning to ARC Release Notes
LLVM Automatic Reference Counting

答案 1 :(得分:3)

使用strong

在头文件中将AVAudioPlayer用作ivar
@property (strong,nonatomic) AVAudioPlayer *audioPlayer

答案 2 :(得分:3)

如果您需要同时播放多个AVAudioPlayers,请创建一个NSMutableDictionary。将密钥设置为文件名。通过委托回调从Dictionary中删除,如下所示:

-(void)playSound:(NSString*)soundNum {


    NSString* path = [[NSBundle mainBundle]
                      pathForResource:soundNum ofType:@"m4a"];
    NSURL* url = [NSURL fileURLWithPath:path];

    NSError *error = nil;
    AVAudioPlayer *audioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];

    audioPlayer.delegate = self;

    if (_dictPlayers == nil)
        _dictPlayers = [NSMutableDictionary dictionary];
    [_dictPlayers setObject:audioPlayer forKey:[[audioPlayer.url path] lastPathComponent]];
    [audioPlayer play];

}

-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {        
   [_dictPlayers removeObjectForKey:[[player.url path] lastPathComponent]];
}