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, в противном случае она работает без нареканий.
3 ответа
Проблема заключается в том, что при компиляции с ARC вам необходимо сохранять ссылку на экземпляры, которые вы хотите поддерживать, поскольку компилятор автоматически исправит "несбалансированный" alloc
вставив release
звонки (по крайней мере, концептуально, читайте пост в блоге Mikes Ash для более подробной информации). Вы можете решить эту проблему, назначив экземпляр свойству или переменной экземпляра.
В случае 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 Автоматический подсчет ссылок
Используйте AVAudioPlayer в качестве ивара в заголовочном файле с strong
:
@property (strong,nonatomic) AVAudioPlayer *audioPlayer
Если вам нужно одновременно играть несколько 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]];
}