95 votes

Comment fonctionne le pool d'autorelease NSAutoreleasePool ?

Si je comprends bien, tout ce qui est créé avec un alloc , nouveau o copie doit être libéré manuellement. Par exemple :

int main(void) {
    NSString *string;
    string = [[NSString alloc] init];
    /* use the string */
    [string release];
}

Ma question, cependant, est que cela ne serait-il pas tout aussi valable? :

int main(void) {
    NSAutoreleasePool *pool;
    pool = [[NSAutoreleasePool alloc] init];
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
    [pool drain];
}

68voto

kperryua Points 6905

Oui, votre deuxième extrait de code est parfaitement valide.

Chaque fois que -autorelease est envoyé à un objet, il est ajouté au pool d'autorelease le plus interne. Lorsque le pool est vidé, il envoie simplement -release à tous les objets du pool.

Les pools d'autorelease sont simplement une commodité qui vous permet de différer l'envoi d'autorelease jusqu'à "plus tard". Ce "plus tard" peut survenir à plusieurs endroits, mais le plus courant dans les applications Cocoa GUI est à la fin du cycle de la boucle d'exécution actuelle.

37voto

mmalc Points 7663

NSAutoreleasePool : vidange vs. libération

Puisque la fonction de drain y release semblent prêter à confusion, il peut être utile de les clarifier ici (bien que ce sujet soit traité dans le document intitulé la documentation ...).

Strictement parlant, du point de vue de l'image globale drain es pas équivalent à release :

Dans un environnement de comptage de référence, drain effectue les mêmes opérations que release Les deux sont donc équivalents en ce sens. Pour insister, cela signifie que vous pas faire fuir une piscine si vous utilisez drain plutôt que release .

Dans un environnement de collecte d'ordures, release n'est pas une option. Il n'a donc aucun effet. drain En revanche, l'indication au collecteur qu'il doit "collecter si nécessaire". Ainsi, dans un environnement de collecte de déchets, l'utilisation de drain aide le système à équilibrer les balayages de collecte.

17voto

Neovibrant Points 476

Comme déjà indiqué, votre deuxième extrait de code est correct.

J'aimerais suggérer une façon plus succincte d'utiliser le pool d'autorelease qui fonctionne dans tous les environnements (comptage des références, GC, ARC) et qui évite également la confusion drain/release :

int main(void) {
  @autoreleasepool {
    NSString *string;
    string = [[[NSString alloc] init] autorelease];
    /* use the string */
  }
}

Dans l'exemple ci-dessus, veuillez noter le @autoreleasepool bloc. Ceci est documenté aquí .

7voto

kperryua Points 6905

Non, vous avez tort. La documentation indique clairement qu'en mode non-GC, -drain est équivalent à -release, ce qui signifie que le NSAutoreleasePool va pas être divulguée.

1voto

Wayne Lo Points 1128

J'ai trouvé que ce lien donnait la meilleure explication sur quand et comment utiliser NSAutoReleasePool : AutoReleasePool

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X