Question

Je construis une application iPhone dans laquelle je détache des threads pour effectuer un travail de longue durée en arrière-plan afin de ne pas accrocher l'interface utilisateur. Je comprends que les threads ont besoin d’instances NSAutoreleasePool pour la gestion de la mémoire. Ce dont je ne suis pas sûr, c’est que la méthode thread appelle une autre méthode. Cette méthode nécessite-t-elle également un NSAutoreleasePool?

Exemple de code:

- (void)primaryMethod {
    [self performSelectorInBackground:@selector(threadedMethod) withObject:nil];
}

- (void)threadedMethod {
    NSAutoreleasePool *aPool = [[NSAutoreleasePool alloc] init];

    // Some code here

    [self anotherMethod];

    // Maybe more code here

    [aPool drain];
}

- (void)anotherMethod {
    // More code here
}

La raison pour laquelle je pose cette question est que je reçois des erreurs, à savoir que des objets sont en cours de libération automatique sans pool en place et qu'ils "ne font que fuir".

J'ai vu d'autres questions où des personnes n'avaient pas du tout de pools de libération automatique, et je comprenais pourquoi un pool de libération automatique était nécessaire. Je souhaite en particulier savoir si un pool de libération automatique créé dans (dans cet exemple) threadedMethod s'applique aux objets créés dans anotherMethod .

Était-ce utile?

La solution

Pour répondre à votre question, oui, anotherMethod utilise le NSAutoreleasePool que vous avez créé dans threadedMethod, et tout ce que vous libérez automatiquement sera libéré quand unPool sera libéré / vidé.

Il est donc peu probable que votre erreur provienne directement de ce code (sauf s’il en existe d’autres).

Placez un point d'arrêt sur _NSAutoreleaseNoPool (ajoutez-le par son nom dans la fenêtre Points d'arrêt) et exécutez votre code dans le débogueur. Il s'arrête dès que autorelease est appelé sans pool, ce qui devrait résoudre votre problème.

Autres conseils

Dans votre exemple, oui, NSAutoreleasePool contient plusieurs méthodes, car l'appel de [self anotherMethod] est imbriqué dans - (void) threadedMethod .

  • Q: NSAutoreleasePool transmettant plusieurs méthodes?
  • R: Cela dépend:
    1. Oui, à travers les invocations imbriquées.
    2. Parmi les invocations entre frères et soeurs, no.

Et quoi qu'il en soit, l'instance NSAutoreleasePool elle-même sort de la portée lorsque la portée parent disparaît. -dans votre exemple, à la toute fin de - (void) threadedMethod {} .

L'article mentionné précédemment ( http://thegothicparty.com/dev/macos/nsautoreleasepool/ ) est tout à fait clair à ce sujet.

Le pool de libération automatique est transféré à une autre méthode. Toutefois, lorsque votre fonction threadée se termine, vous devez appeler [version de aPool] au lieu de [drain de liste]. Ils sont à peu près équivalents, mais une version de Pool entraîne la libération de NSAutoreleasePool en plus de tous les autres objets du pool. Lorsque votre fonction threadée se termine après l'appel de drain, le pool de libération automatique a toujours un nombre de retenues de +1! Les chances sont, le "tout juste des fuites" objet est une piscine!

EDIT:

Jim Puls a raison de dire que le relâchement et la purge sont équivalents. Les documents Apple indiquent clairement qu'ils sont identiques dans l'environnement non récupéré, et que la vidange est meilleure dans le cas des déchets collectés. Ma faute pour ne pas lire la documentation!

Voici un article qui présente un aperçu général de NSAutoreleasePools - il devrait vous aider à vous orienter dans la bonne direction. Dans la mesure où il existe une pile virtuelle de pools autorelease, la plus haute sera utilisée partout dans votre application, quel que soit le lieu où les objets sont libérés automatiquement.

http://thegothicparty.com/dev/macos/nsautoreleasepool/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top