AVAudioPlayer立即停止播放ARC
我试图通过AVAudioPlayer
播放MP3,我认为这很简单。 不幸的是,这不是工作。 这是我所做的一切:
- 为了testing,我在Xcode中创build了一个新的iOS应用程序(Single View)。
-
我将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]; }
不幸的是,audio开始播放后显然停止。 如果我取消注释sleepForTimeInterval
它播放20秒,然后停止。 只有使用ARC进行编译时才会出现此问题,否则,该工作将完美无瑕。
问题是,在编译ARC时,你需要确保保持对你想保持活动的实例的引用,因为编译器会通过插入release
调用来自动修复“不平衡”的alloc
(至less在概念上,阅读Mikes Ash博客文章更多细节 )。 您可以通过将实例分配给属性或实例variables来解决此问题。
在Phlibbo案例中,代码将被转换为:
- (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 }
而且AVAudioPlayer
会立即停止播放,因为当没有引用时它会被释放。
我自己并没有使用ARC,只是简单地阅读了一下。 请评论我的答案,如果你知道更多关于这个,我会更新与更多的信息。
更多的ARC信息:
过渡到ARC发行说明
LLVM自动引用计数
如果您需要同时播放多个AVAudioPlayers,请创build一个NSMutableDictionary。 将密钥设置为文件名。 通过代理callback从字典中移除,如下所示:
-(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]]; }
使用AVAudioPlayer作为strong
的头文件中的伊娃:
@property (strong,nonatomic) AVAudioPlayer *audioPlayer