2009-10-21 8 views
1

Je reçois ce message d'erreur dans la console:mémoire NSAutorelease fuite

 
*** _NSAutoreleaseNoPool(): Object 0x10d2e0 of class NSPathStore2 
    autoreleased with no pool in place - just leaking 

Je ne peux pas comprendre ce qui est l'erreur?

Merci.

Répondre

12

Ceci est un problème de gestion de la mémoire classique, vous autoreleasing certains objets sans avoir un pool autorelease en place. Autoreleasing n'est pas une magie. Il y a un objet de type NSAutoreleasePool qui garde une trace de tous les objets que vous AutoRelease et « de temps en temps » les libère:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
// An autoreleased object referenced by our pool. 
id object = [NSNumber numberWithInt:1]; 
[pool drain]; 
// Our object no longer valid. 

Chaque thread doit avoir sa propre piscine autorelease. C'est tout à fait logique, car les threads s'exécutent "en même temps" et s'ils partagent un pool auto-libéré commun, ils peuvent libérer un objet pendant que vous travaillez dessus.

Maintenant le point. Il existe un pool autorelease par défaut dans le thread principal de chaque application, ce qui signifie que vous n'avez pas à penser à tout cela et que les objets auto-libérés sont collectés correctement. Mais si vous créez un autre thread, vous êtes généralement obligé de créer également un pool autorelease pour ce thread. Sinon, il n'y a personne pour réclamer les objets autoreleased et ils fuient juste. C'est exactement pourquoi vous obtenez l'avertissement.

fil Leaking sans piscine autorelease peut ressembler à ceci:

- (void) doSomethingInBackground 
{ 
    id object = [NSNumber numberWithInt:1]; 
} 

- (void) someOtherMethod 
{ 
    [self performSelectorInBackground:@selector(doSomethingInBackground); 
} 

La solution est simple: Maintenant, vous avez seulement

- (void) doSomethingInBackground 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    id object = [NSNumber numberWithInt:1]; 
    [pool drain]; 
} 

pour savoir où vous exécutez du code dans un autre thread.

+1

Il devrait être [vidange de la piscine] pas [de sortie de la piscine] ... –

+0

Vous avez raison (je ne travaille que sur l'iOS où il n'y a pas de différence entre les deux). – zoul

+0

Pour faciliter la détection de la fuite, cassez __NSAutoreleaseNoPool dans gdb. – gaspard

2

On dirait que vous avez donné naissance à une méthode sur un nouveau thread (éventuellement à l'aide + (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument;)

Toute méthode qui fonctionne sur son propre thread aura besoin d'avoir une configuration de pool autorelease pour attraper tous les objets autoreleased:

- (void)myLovelyThreadedMethod 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    ... // your code here 

    [pool release]; 
}