2010-03-23 3 views
1

J'ai vu une ligne similaire code flottaient dans le code Apples:fuite de mémoire à l'aide (void) alloc

(void)[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self]; 

URLRequest est ma propre classe personnalisée. Je n'ai pas écrit ça et je pense que le gars qui l'a attrapé vient de l'exemple d'Apple. Pour moi, cela devrait fuir et quand je l'ai testé, je suis sûr qu'il fuit 16 octets. Est-ce que cela serait? Je sais comment réparer si c'est le cas mais n'était pas sûr car il a été pris du code d'Apple.

EDIT: Le problème était avec le SDK, pas le code ci-dessus. Voir la réponse ci-dessous pour plus de détails

+0

Je n'utiliserais pas de code avec une méthode commençant par '-initializeSomething': quiconque ne connait pas assez Objective-C pour nommer sa méthode' -initSomething' n'évitera probablement pas correctement les fuites: alors que peut sembler sévère, une simple erreur comme celle-ci pourrait vraiment montrer une méconnaissance de l'ensemble d'outils. –

+1

:/Bien que vous ayez un point n'est pas un choix de nit? Il pourrait avoir une haine passionnée pour raccourcir les mots. Le reste de son code ne fuit pas non plus – Rudiger

+0

Rudiger: Suivre une convention de nommage correcte est/toujours/une bonne idée. –

Répondre

3

Je pensais que je pourrais mettre à jour cela car après d'autres tests et la sortie de iOS4, il a changé.

Le code ci-dessus ne fuit pas et l'empreinte mémoire de l'application revient à la normale, même après 200 itérations du code. La fuite s'est produite dans iOS3 mais était très petite, dans iOS4 il a complètement disparu à la fois dans le simulateur et l'appareil.Certains peuvent se demander pourquoi vous voudriez implémenter ce code mais cela fonctionne et a du sens quand vous traitez avec beaucoup de différents NSURLConnections dans votre code qui s'exécute simultanément.

2

Pas du tout certain de savoir ce que ce code est supposé accomplir. Cela semble briser toutes les conventions sur les méthodes d'initialisation. Quel est le point de renvoyer un pointeur vide d'une méthode d'initialisation? Le point entier d'une méthode d'initialisation est de retourner un objet. Où dans les exemples de code d'Apple avez-vous vu cela? Cela dit, je ne vois pas pourquoi cela fuirait. Comme il ne renvoie pas d'objet, il n'y a rien à divulguer à l'extérieur de la méthode. Il peut y avoir quelque chose à l'intérieur qui fuit.

Edit:

It basically does an NSURLConnection. Because we are submitting a lot of forms with a lot of different values we put it in an external class. All the delegate methods like didFailWithError: are in NSURLRequest and connectionDidFinishLoading just passes the data to its delegate. So it doesn't really need to return anything as it is done through a delegate method.

Oui, vous avez besoin de revoir cela. À l'heure actuelle, cette méthode est juste une catastrophe en attente de se produire. Si rien d'autre, tout le monde regarde ce code sera complètement confus au sujet de ce que vous faites.

Si vous n'avez pas besoin de conserver l'objet créé, déplacez son allocation et nettoyez entièrement dans une méthode. Changez le préfixe du nom de la méthode de "initialize" à quelque chose comme "setup", "configure", "acquérir" etc, donc le nom n'implique pas qu'il crée et renvoie et object.

Si vous avez besoin d'une instance one shot d'une classe particulière, utilisez une méthode de classe comme Michael Aaron Safyan suggérée (encore sans initialize dans le nom.) La méthode de classe doit initialiser en interne une instance, effectuer les opérations données à n'importe où, puis libérer l'instance. De cette façon, vous n'aurez pas à vous soucier des fuites et tous ceux qui liront votre code (y compris vous-même des mois plus tard) comprendront immédiatement ce que fait le code.

+0

Il fait essentiellement un NSURLConnection. Parce que nous soumettons beaucoup de formulaires avec beaucoup de valeurs différentes, nous les mettons dans une classe externe. Toutes les méthodes déléguées comme didFailWithError: sont dans NSURLRequest et connectionDidFinishLoading transmet simplement les données à son délégué. Donc, il n'a pas vraiment besoin de retourner quoi que ce soit comme cela est fait par une méthode déléguée. – Rudiger

+0

Oui. Il m'a fallu des années pour comprendre et puis le gars m'a montré le code de démo d'Apple d'où il l'a eu. Pensez que je pourrais scrapper le tout et recommencer. – Rudiger

2

Oui. Ceci est une fuite, qui peut facilement être résolu en ajoutant un autorelease:

 
[[[URLRequest alloc] initializeRequestWithValues:postBody url:verifySession httpHeader:nil delegate:self] autorelease]; 

Peut-être une meilleure solution serait de créer une fonction de classe qui fait cela:

 
@interface URLRequest 
{ 
    // ... 
} 
// ... 
+ (void) requestWithValues:/* ... */ 
// ... 
@end 

Ensuite, vous pouvez simplement utiliser [ URLRequest requestWithValues:/* ... * /] sans invoquer alloc.

+0

Je ne peux pas réellement appeler autorelease parce que le NSURLConnection dans URLRequest pourrait répondre après la boucle d'exécution. Je l'ai essayé et ça plante. Je vais regarder dans votre autre solution bien que cela sonne mieux. – Rudiger

+0

@Rudiger, si vous avez besoin que l'instance persiste, vous devez l'enregistrer en tant que membre de l'objet qui l'utilise et utiliser une version normale sur le membre dans la méthode dealloc. –

+0

+1 Une méthode de classe est certainement la voie à suivre – TechZen