2010-01-29 7 views
-1

J'ai une très grosse boucle dans mon programme, et j'utilise beaucoup de variables temporaires et d'instances. Comme ma boucle continue à fonctionner, le programme utilise de plus en plus de mémoire jusqu'à ce qu'il tombe en panne. Puis-je obtenir des conseils sur la façon de gérer correctement la mémoire dans cette situation? Ma question principale est, pourquoi le code suivant est-il faux?Gestion de la mémoire Objective-C pour les grandes boucles

Voici le code qui est à l'origine de la fuite:

(void) processTrackValues: (NSMutableArray *) {balises
NSImage * trackArt = [balises objectAtIndex: 5];
NSMutableArray * tempArtArray = [[NSMutableArray alloc] init];
[tempArtArray addObject: trackArt];
[version de tempArtArray];
}

J'ai aussi essayé:

(void) processTrackValues: (NSMutableArray *) {balises
NSImage * trackArt = [balises objectAtIndex: 5];
NSMutableArray * tempArtArray = [[NSMutableArray alloc] init];
[tempArtArray addObject: trackArt];
[version trackArt];
[version de tempArtArray];
}

+0

code serait utile. –

+0

Il y a beaucoup de code. Je ne sais pas comment rendre cette question plus spécifique:/ – Chetan

+0

l'objectif C ne possède-t-il pas un éboueur? –

Répondre

6

La réponse d'Adam est correcte. En pseudo code:

unsigned int iters = 0; 
NSAutoreleasePool *p = nil; 
while(1) { 
    if (!p) p = [[NSAutoreleasePool alloc] init]; 
    ... do stuff here ... 
    if (iters == 1000) { 
    iters = 0; 
    [p drain]; 
    p = nil; 
    } 
} 

La réutilisation d'objets temporaires est généralement une perte de temps et une fragilité. Franchement, vous devriez probablement faire la danse de la piscine autorelease une fois pour chaque itération à travers la boucle et ignorer tous les compteurs stupides et autres jusqu'à ce que vous ayez instrumenté la preuve qu'il y a un overhead autrement.

Quelque chose comme:

NSAutoreleasePool *p = nil; 
while(1) { 
    p = [[NSAutoreleasePool alloc] init]; 
    ... do stuff here ... 
    [p drain]; 
} 
+0

@bbum, il y a quelque temps, Mike Ash a fait des recherches et a trouvé que drainer la piscine à chaque itération était plus efficace. Je pense que c'était assez récent pour inclure le runtime x86_64/ARM, mais je ne peux pas faire glisser une référence maintenant. –

+0

Est-ce que cela fonctionnerait pour libérer des objets alloués par des fonctions appelées sous '... do stuff here ...'? Ou ces fonctions ont-elles besoin de leurs propres autoreleasepools? – Chetan

+0

@Chetan: Les pools Autorelease sont poussés sur une pile de pools lorsqu'ils sont créés. Lorsque vous appelez '[obj autorelease]', l'objet est placé sur le pool en haut de la pile. Donc, les objets créés dans les fonctions sous '... font des choses ici ...' seront automatiquement libérés sur le pool en haut de la pile. – mipadi

3

Vous pouvez essayer de réutiliser vos objets temporaires ou créer votre propre AutoReleasePool pour les objets et relâchez 1000 itérations environ.