2010-04-14 3 views
5

J'ai essayé des fuites essayant de trouver quelle fonction n'est pas désaffectée (je suis encore nouveau à ceci) et pourrait vraiment utiliser un aperçu expérimenté. J'ai ce code qui semble être le coupable. Chaque fois que j'appuie sur le bouton qui appelle ce code, 32kb de mémoire sont en outre alloués à la mémoire et lorsque le bouton est relâché, cette mémoire n'est pas libérée.Comment trouver le robinet qui fuit qui se charge dans Malloc 32kb

Ce que j'ai trouvé que chaque fois que AVAudioPlayer est appelé à jouer un fichier m4a, la fonction finale pour analyser le fichier m4a est MP4BoxParser::Initialize() et à son tour, alloue 32 Ko de mémoire par Cached_DataSource::ReadBytes

Ma question est, comment Je vais désallouer cela après qu'il est fini de sorte qu'il ne continue pas allouer 32kb chaque fois que le bouton est pressé?

Toute aide que vous pourriez fournir est grandement appréciée!

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

//stop playing 
theAudio.stop; 


// cancel any pending handleSingleTap messages 
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(handleSingleTap) object:nil]; 

UITouch* touch = [[event allTouches] anyObject]; 


NSString* filename = [g_AppsList objectAtIndex: [touch view].tag]; 

NSString *path = [[NSBundle mainBundle] pathForResource: filename ofType:@"m4a"]; 
theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 
theAudio.delegate = self; 
[theAudio prepareToPlay]; 
[theAudio setNumberOfLoops:-1]; 
[theAudio setVolume: g_Volume]; 
[theAudio play]; 
} 

Répondre

2

L'astuce pour la gestion de la mémoire à Cocoa est d'équilibrer les appels à alloc, retain ou copy avec un appel ultérieur à release.

Dans ce cas, vous envoyez alloc pour initialiser votre variable theAudio, mais vous n'envoyez jamais release.

En supposant que vous n'ayez qu'un seul son à la fois, la meilleure façon d'y parvenir est d'utiliser une propriété sur votre contrôleur (celle qui a cette méthode -touchesBegan). La déclaration de propriété ressemblerait à ceci:

@property (nonatomic, retain) AVAudioPlayer * theAudio; 

Vous aurez alors besoin de mettre theAudio à nil dans votre init méthode:

theAudio = nil; // note: simple assignment is preferable in init 

Et assurez-vous de libérer la variable dans votre méthode dealloc:

[theAudio release]; 

Maintenant, votre touchesBegan pourrait ressembler à ceci:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    //stop playing 
    theAudio.stop; 
    ... 
    AVAudioPlayer * newAudio = [[AVAudioPlayer alloc] initWithContentsOfUrl:...]; 
    self.theAudio = newAudio; // it is automatically retained here... 

    theAudio.delegate = self; 
    [theAudio prepareToPlay]; 
    [theAudio setNumberOfLoops:-1]; 
    [theAudio setVolume: g_Volume]; 
    [theAudio play]; 

    [newAudio release];  // ...so you can safely release it here 
} 
+0

pourriez-vous expliquer quelle méthode 'init' vous référez? (encore, désolé je suis très nouveau à ceci) – iwasrobbed

+0

et aussi, juste pour vérifier je comprends ceci: Ce que vous dites est que je dois charger l'audio dans une variable allouée additionnelle de sorte que je n'essaye pas de libérer le courant Fichier m4a (ou appelez éventuellement un morceau de mémoire désalloué) Je suppose que ma question est, est-ce que 'theAudio' allouera toujours de la mémoire supplémentaire à chaque fois puisqu'il n'est pas dellocated jusqu'à ce que' dealloc() 'soit appelé? – iwasrobbed

+0

Normalement parlant, chaque contrôleur possède à la fois une méthode '-init' et une méthode' dealloc'. Puis-je supposer que cela en tant que «UIViewController»? Si c'est le cas, la méthode appropriée pour remplacer est -initWithNibName: bundle: Une autre alternative consiste à définir votre ivar à nil dans la méthode 'viewDidLoad'. –

1

Cette ligne semble me coupable:

theAudio=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 

Quand cette ressource se libèrent?

Questions connexes