AVAudioPlayer deja de jugar inmediatamente con ARC

Estoy tratando de reproducir un MP3 a través de AVAudioPlayer lo que pensé que era bastante simple. Desafortunadamente, no está funcionando del todo. Aquí está todo lo que hice:

Código:

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

Desafortunadamente, el audio obviamente se detiene justo después de que comienza a reproducirse. Si sleepForTimeInterval el comentario de sleepForTimeInterval se reproduce durante 20 segundos y se detiene después. Este problema ocurre solo al comstackr con ARC, de lo contrario, funciona sin problemas.

El problema es que al comstackr con ARC, debes asegurarte de mantener una referencia a las instancias que quieras mantener activas ya que el comstackdor corregirá automáticamente la alloc “desequilibrada” insertando llamadas de release (al menos conceptualmente, lee la publicación del blog de Mikes Ash para más detalles ). Puede resolver esto asignando la instancia a una propiedad o una variable de instancia.

En el caso de Phlibbo, el código se transformará en:

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

Y el AVAudioPlayer dejará de reproducirse inmediatamente ya que se desasignará cuando no quede ninguna referencia.

No he usado ARC y acabo de leerlo brevemente. Comente mi respuesta si conoce más sobre esto y lo actualizaré con más información.

Más información ARC:
Transición a las notas de la versión de ARC
Contador de referencia automático LLVM

Si necesita reproducir varios AVAudioPlayers al mismo tiempo, cree un NSMutableDictionary. Establezca la clave como el nombre del archivo. Eliminar del diccionario a través de la callback de delegado, así:

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

Utilice AVAudioPlayer como un ivar en el archivo de encabezado con strong :

 @property (strong,nonatomic) AVAudioPlayer *audioPlayer