2010-06-30 7 views
2

Je vais rester court et doux - Je construis une application juste pour la pratique avant de m'acheter le programme développeur iPhone. J'expérimente avec le AVFoundation.framework et je continue à courir dans un bogue qui me laisse seulement jouer le premier son que j'initialise dans mon code. Pensez-vous que l'un de vous pourrait m'aider? Merci d'avance!! :)Bug dans la classe AVAudioPlayer?

vue contrôleur

-(IBAction)play { 
    if (segments.selectedSegmentIndex == 0) { 
     NSLog(@"Segment = 0"); 
     NSBundle *bundle = [NSBundle mainBundle]; 
     NSString *path = [bundle pathForResource:@"meow" ofType:@"wav"]; 

     if (path != nil) { 
      NSURL *url = [NSURL fileURLWithPath:path]; 
      AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL]; 
      [player prepareToPlay]; 
      [player play]; 
     } 
    } 

    else if (segments.selectedSegmentIndex == 1) { 
     NSLog(@"Segment = 1"); 
     NSBundle *bundle = [NSBundle mainBundle]; 
     NSString *path2 = [bundle pathForResource:@"meowloud" ofType:@"wav"]; 

     if (path2 != nil) { 
      NSURL *url2 = [NSURL fileURLWithPath:path2]; 
      AVAudioPlayer *player2 = [[AVAudioPlayer alloc]initWithContentsOfURL:url2 error:NULL]; 
      [player2 prepareToPlay]; 
      [player2 play]; 
//   [player2 release]; 
     } 
    } 

    text1.textColor = [UIColor clearColor]; 
    text2.textColor = [UIColor clearColor]; 
    text3.textColor = [UIColor clearColor]; 
    text4.textColor = [UIColor clearColor]; 

} 

Lorsque ce code est exécuté, seul le meow.wav est exécutée, quel que soit le segment sélectionné.

+0

Vous avez des fuites de mémoire dans ce code, mais cela ne devrait pas empêcher la lecture correcte du son. Je vais d'abord aborder les problèmes de son: le texte correct est-il envoyé à la console lorsque vous sélectionnez le second index de segment? c'est-à-dire que la console affiche "Segment = 1"? –

Répondre

3

Votre code a quelques fuites de mémoire. Vous allouez des instances de AVAudioPlayer dans votre méthode play, mais vous ne publiez jamais ces instances. Voir Cocoa's memory management qguidelines pour plus de détails. Comme les instances d'AVAudioPlayer doivent rester en mémoire pour être lues, la solution la plus simple consiste à ajouter une variable membre à votre classe viewController et à la configurer en tant que propriété retain. Pour les besoins de Don't Repeat Yourself (DRY), je suggère également d'ajouter une méthode qui encapsule tout le code nécessaire pour lire un seul fichier wav.

Voici comment j'écrire ce contrôleur de vue:

MyViewController.h

@interface MyViewController : UIViewController 
{ 
    AVAudioPlayer *player; 
} 
@property(nonatomic, retain) AVAudioPlayer *player; 
- (void)playWavFile:(NSString *)fileName; 
- (IBAction)play; 
@end 

MyViewController.m

@synthesize player; 

- (void)dealloc { 
    [player release]; 
} 

- (void)playWavFile:(NSString *)fileName { 
    NSBundle *bundle = [NSBundle mainBundle]; 
    NSString *path = [bundle pathForResource:fileName ofType:@"wav"]; 

    if (path != nil) { 
     AVAudioPlayer *newPlayer; 
     NSURL *url = [NSURL fileURLWithPath:path]; 
     newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url 
                  error:NULL]; 
     [self setPlayer:newPlayer]; 
     [newPlayer release]; 

     [newPlayer prepareToPlay]; 
     [newPlayer play]; 
    } 
} 

- (IBAction)play { 

    if (segments.selectedSegmentIndex == 0) { 
     [self playWavFile:@"meow"]; 
    } 
    else if (segments.selectedSegmentIndex == 1) { 
     [self playWavFile:@"meowloud"]; 
    } 
} 
+0

Merci beaucoup! Je vais essayer et rendre compte. En attendant, comment pouvez-vous [release newPlayer]; avant d'appeler prepareToPlay et de jouer? – esqew

+0

Vous pouvez le faire à cause de la ligne au-dessus. '[self setPlayer: nouveauPlayer]' utilise l'accesseur de propriété pour la variable membre 'player', ce qui signifie qu'il est automatiquement conservé (car la propriété a été définie comme une propriété retain). Une fois cet appel effectué, votre viewController "possède" le lecteur, vous pouvez donc appeler 'release' en toute sécurité pour équilibrer l'appel à' alloc'. –

+0

Merde ... ça ne marche pas. Je reçois: ** signal reçu programme:. « SIGABRT » ** 2010-06-30 19: 48: 41,334 Merrrw [4713: 207]! *** Mettre fin à l'application du fait exception uncaught 'NSInvalidArgumentException', raison: '- [AVAudioPlayer initWithContentsOfURL:]: sélecteur non reconnu envoyé à l'instance 0x6302f80' Des idées? Merci encore pour toute l'aide. :) – esqew