AVAudioPlayer перестает играть сразу с ARC
Я пытаюсь воспроизвести MP3 через AVAudioPlayer
, который, как я думал, довольно прост. К сожалению, он не совсем работает. Вот все, что я сделал:
- Для тестирования я создал новое приложение для iOS (Single
View) в 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, в противном случае она работает безупречно.
Ответы
Ответ 1
Проблема заключается в том, что при компиляции с ARC вам необходимо следить за экземплярами, которые вы хотите сохранить в качестве компилятора автоматически установит "неуравновешенный" alloc
, вставив release
вызовы (по крайней мере, концептуально, прочитайте
И AVAudioPlayer
он немедленно перестанет воспроизводиться, когда он освободится, когда ссылка не останется.
Я не использовал ARC сам и только что прочитал об этом ненадолго. Прокомментируйте мой ответ, если вы знаете больше об этом, и я обновлю его с дополнительной информацией.
Дополнительная информация ARC:
Ответ 2
Используйте AVAudioPlayer как ivar в файле заголовка с strong
:
@property (strong,nonatomic) AVAudioPlayer *audioPlayer
Ответ 3
Если вам нужно несколько AVAudioPlayers, играющих одновременно, создайте NSMutableDictionary. Задайте ключ как имя файла. Удалите из словаря через обратный вызов делегата следующим образом:
-(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]];
}