2009-08-30 9 views
1

Souhaitez-il jeter plus de lumière si je disais que fetchHTML a été appelé dans un thread séparé? Je vois aussi plusieurs messages dans la console de débogage tels que:stringWithContentsOfURL fuite de mémoire

_NSAutoreleaseNoPool(): Object 0xd92860 de classe NSCFDictionary autoreleased sans piscine en place - juste une fuite

_NSAutoreleaseNoPool(): Object 0xd92800 de classe NSCFString autoreleased avec Je n'ai pas de piscine en place - juste une fuite

Je suis nouveau dans le développement d'applications iPhone, Objective-C mais pas nouveau en programmation ou en C/C++. J'utilise l'outil de performance des fuites et il montre beaucoup de fuites. Ceci est une fuite de 10,5 kb et il se produit sur la ligne:

NSString * xml = [NSString stringWithContentsOfURL:urlobj]; 

La trace de la pile sur ce ci-dessous est la suivante:

stringWithContentsOfURL 
initWithContentsOfURL 
initWithDataOfEncoding 
... 

Est-ce que quelqu'un a une idée pourquoi cela doit se produire. Je suis sous l'impression que je reçois un objet autorelease ici et je peux le retourner à l'appelant sans appeler retenez. Je n'utilise pas l'objet xml pour stocker dans une variable d'instance, juste pour le traitement.

Voici le code de fonction:

- (NSString *) fetchHTML: (NSString*) url{ 
    @try 
    { 
     NSURL* urlobj = [NSURL URLWithString:url]; 
     NSString * xml = [NSString stringWithContentsOfURL:urlobj]; 
     return xml; 
    } 
    @catch(NSException *ex){ 
     NSLog(@"Error fetchingHTML"); 
     return nil; 
    } 
    return nil; 
} 
+0

'Cela donnerait-il plus de lumière si je disais que fetchHTML était appelé dans un thread séparé?' Oui. Vous avez suivi la documentation et créé un pool autorelease pour le thread, non? De préférence, l'une des premières choses à faire, sinon la première, dans le point d'entrée méthode/fonction pour le thread engendré. – johne

Répondre

1

Eh oui; ça ne devrait pas fuir.

Il peut s'agir d'un faux positif dans la mesure où le sous-système d'URL met en cache le contenu de l'URL de telle sorte que le pointeur n'est plus visible pour l'analyse des fuites. Si vous le pouvez, recommencez le test sur Snow Leopard. La détection des fuites sur Snow Leopard est significativement plus rapide et plus précise. Je suis entièrement d'accord avec vous que cela ne devrait pas causer de fuite.

1

J'ai codé dans Cocoa/Objective-C depuis 2 ans maintenant, et cela semble devoir fonctionner. Cela étant dit, je remarque que la documentation d'Apple indique que la méthode stringWithContentsOfURL: est deprecated. Peut-être que cela fonctionnerait comme suit:

NSString * xml = [[NSString alloc] 
        initWithContentsOfURL:urlobj 
           encoding:NSASCIIStringEncoding 
            error:nil]; 
return [xml autorelease]; 
+0

Je peux vraiment essayer ça. Est-ce que je vous dirais que le fetchHTML est appelé dans un fil séparé. Ai-je besoin de créer un nouveau autoreleasepool? Dans ma console de débogage, je vois plusieurs messages comme "Objet **** de la classe *** autoreleased avec aucun pool en place - juste fuite –

+0

Je crains de ne pas être un expert sur l'utilisation threaded des autorelease pools. .? ne semble que cela pourrait être le problème, mais pourquoi ne pas ajouter cette information à la question –

1

Comme l'indique le message d'erreur, il n'y a pas de groupe de libération automatique pour la chaîne à entrer, et cela crée une fuite. NSAutoreleasePools existe sur une base par thread. Cocoa en crée un dans la boucle d'événement principal du thread principal, mais c'est le seul qu'il crée pour vous. Si vous n'êtes pas dans le thread principal et que vous devez traiter des objets autoreleased, vous devez également créer un pool autorelease pour ce thread.

Vous pouvez consulter le NSAutoreleasePool docs pour plus d'informations sur le fonctionnement des piles de pool autorelease.

+0

Merci, j'ai ajouté une enveloppe de autoreleasepool autour de ma fonction de fil, mais je reçois une erreur de objc_msgSend Voici le code:. NSAutoreleasePool * piscine = [[NSAutoreleasePool alloc] init]; [tableauDonnees replaceObjectAtIndex: 2 withObject: "Et maintenant"];? [sortie de la piscine]; Toute idée de ce qui se passe ici –

+0

Essayez [tableauDonnees replaceObjectAtIndex: 2 withObject: @ "maintenant quoi"]; Notez le symbole @. –

+0

En effet, cette ligne replaceObjectAtIndex ... ne peut pas avoir fonctionné avant que le pool autorelease soit là non plus. – Chuck