2009-11-06 3 views
1

Quand je compile mon projet iPhone (dans la ligne de commande), la sortie du journal ressemble à:message du journal de fuite de mémoire tout en * compilation * avec Xcode pour l'iPhone

2009-11-05 22:19:57.494 xcodebuild[51128:613] warning: compiler 'com.apple.compilers.llvm.clang.1_0.analyzer' is based on missing compiler 'com.apple.compilers.llvm.clang.1_0.analyzer' 
=== BUILDING NATIVE TARGET Foo OF PROJECT foo WITH THE DEFAULT CONFIGURATION (AdHoc) === 

Checking Dependencies... 
2009-11-05 22:19:58.032 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x722d410 of class NSCFString autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0xfea624 0x2620e34 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 
2009-11-05 22:19:58.035 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x720b370 of class NSCFDictionary autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0x2621454 0x262012a 0x2620e53 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 
2009-11-05 22:19:58.038 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x720b370 of class NSCFDictionary autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0x2621454 0x2620174 0x2620e53 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 
2009-11-05 22:19:58.044 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x7111690 of class NSCFDictionary autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0x2611215 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 
2009-11-05 22:19:58.078 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x7114c10 of class NSCFNumber autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0x2611242 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 
2009-11-05 22:19:58.088 xcodebuild[51128:5b07] *** _NSAutoreleaseNoPool(): Object 0x71a28c0 of class NSCFNumber autoreleased with no pool in place - just leaking 
Stack: (0x97257f4f 0x97164432 0x2611286 0x2620f50 0x2620cbd 0x2384304 0x23957a3 0x948b76f0 0x948b8d35 0x948ae3c5 0x948aeaa8 0x2620922 0x9716adfd 0x9716a9a4 0x926bd155 0x926bd012) 

Ensuite, il y a un tas de traitement commandes (un groupe de setenv s), puis les commandes CompileC commencent, dont certains (mais pas tous, peut-être 10% d'entre eux) sont suivies avec plus de plaintes au sujet des fuites.

Cependant, il compile correctement et fonctionne correctement. Je l'ai couru avec des fuites, et il a trouvé deux fuites de 16 octets que je ne peux pas encore traquer, mais rien de l'ordre du gâchis des messages ci-dessus. Et d'ailleurs, comment sait-il qu'il y a une fuite quand c'est compiler?

Répondre

6

En résumé, le compilateur est plus intelligent que vous ne le pensez;). Ces erreurs signifient que vous autoreliez divers objets (NSString, NSDictionary, NSNumber) dans un contexte qui n'a pas alloué de NSAutoreleasePool. Par exemple, le fichier main.m d'un projet doit déclarer une piscine autorelease:

int main(int argc, char *argv[]) { 

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 
    int retVal = UIApplicationMain(argc, argv, nil, nil); 
    [pool release]; 
    return retVal; 
} 

Dans de nombreuses applications, ce sera la seule piscine qui est jamais alloué. Sans cette piscine, vous ne pouvez rien relâcher, et si vous essayez d'auto-lâcher, il n'y a pas de piscine à faire pour que cela devienne une fuite. Vérifiez votre fonction principale pour vous assurer que NSAutoreleasePool est alloué.

Il existe d'autres situations dans lesquelles vous pouvez souhaiter déclarer un autre NSAutoreleasePool. La situation la plus courante est lorsque les sélecteurs sont invoqués dans un nouveau thread. Chaque thread doit avoir son propre NSAutoreleasePool. Pour plus d'informations sur ce sujet, voir la diapositive 36 de Stanford University CS193P Conférence 10:

- (void)someAction:(id)sender { 
    // Fire up a new thread 
    [NSThread detachNewThreadSelector:@selector(doWork:) withTarget:self object:someData]; 
} 

- (void)doWork:(id)someData { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    [someData doLotsOfWork]; 

    // Message back to the main thread 
    [self performSelectorOnMainThread:@selector(allDone:) withObject:[someData result] waitUntilDone:NO]; 
    [pool release]; 
} 

Un autre exemple est une boucle coûteuse où vous autoreleasing beaucoup d'objets. Plutôt que de laisser le NSAutoreleasePool principal atteindre une taille énorme, vous constaterez que la création d'un nouveau NSAutoreleasePool tous les N fois autour de la boucle aidera à réduire au minimum l'utilisation de vos ressources. Une partie de ce code a également été empruntée aux diapositives de cours énumérés ci-dessus:

int N = 10; 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

for (int i = 0; i < someLargeNumber; i++) { 
    NSString *string = ...; 
    string = [string lowercaseString]; 
    string = [string stringByAppendingString:...]; 
    NSLog(@“%@”, string); 

    // Release the temporary pool and allocate a new one 
    // every N times around the loop 

    if (i % N == 0) { 
     [pool release]; 
     pool = [[NSAutoreleasePool alloc] init]; 
    } 
} 

[pool release]; 

Peut-être que vous avez un code comme celui-ci qui ne sont pas toujours ou libérer alloue les piscines comme prévu. Je ne suis pas sûr que le compilateur soit assez intelligent pour remarquer ce genre de problème.

+0

En fait, je * * ai un pool de libération automatique attribué avant mon UIApplicationMain; Cependant, c'est dans un fichier qui a déjà été compilé, et je fais juste un lien avec ce projet. Alors peut-être que le compilateur est trop intelligent pour son propre bien? –

+0

Hmmm, cela semblait être le problème. J'ai réinstallé le pool d'autorelease dans le projet et les avertissements ont disparu. Je suppose que ça devenait confus. –

+0

Son possible que c'est un problème avec Xcode lui-même, je n'ai jamais essayé de compiler à partir de la ligne de commande, donc je n'ai pas vu cela avant. Avez-vous simplement ajouté le fichier à votre projet afin de toujours le compiler? –

0

La plupart des programmes fonctionneront correctement même avec des fuites, mais de toute façon je ne pense pas que vous montriez assez d'informations. Ma conjecture est que vous envoyez un objet autorelease où il n'y a pas de piscine en place ?. lol. Avez-vous essayé les instruments?

1

Ces avertissements peuvent être dus à des fuites dans les outils eux-mêmes. Mais sinon, ces types de messages sont ce que vous voyez si vous exécutez un thread ou effectuez un sélecteur en arrière-plan sans mettre en place un pool autorelease.