AVAudioPlayer deja de jugar inmediatamente con ARC

Estoy intentando reproducir un MP3 a través de AVAudioPlayer que pensé que era bastante simple. Desafortunadamente, no funciona del todo. Aquí es lo único 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 sleepForTimeInterval se reproducirá durante 20 segundos y se detendrá después. Este problema ocurre solo cuando se comstack con ARC; de lo contrario, funciona sin problemas.

El problema es que al comstackr con ARC debe asegurarse de mantener una reference a las instancias que desea mantener con vida, ya que el comstackdor solucionará automáticamente la alloc "desequilibrada" insertando llamadas de release (al less conceptualmente, lea la publicación del blog de Mikes Ash para mas detalles ) Puede resolver esto asignando la instancia a una propiedad o a una variable de instancia.

En 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 AVAudioPlayer dejará de reproducirse inmediatamente, ya que se desasigna cuando no queda ninguna reference.

No he utilizado ARC yo mismo y acabo de leer sobre él brevemente. Por favor, comenta mi respuesta si sabes 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
LLVM conteo automático de references

Si necesita múltiples AVAudioPlayers jugando al mismo time, cree un NSMutableDictionary. Establezca la key como el nombre del file. Eliminar del dictionary a través de Devolución de llamada de delegado, como sigue:

 -(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 ivar en el file de encabezado con strong :

 @property (strong,nonatomic) AVAudioPlayer *audioPlayer