autorelease précoce

2»

Réponses

  • chaps31chaps31 Membre
    21:24 modifié #32
    Parfait, belle outil, bon par contre j'ai des erreurs que je ne comprends pas...

    1°) Uninitialized recever, sur : "theValue=[theRecord..."
    - (id)tableView:(NSTableView *) aTableView&nbsp; objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex<br />{ <br />	<br />	id theRecord, theValue;<br />	switch ([aTableView tag])<br />	{<br />		case 0:if([clientsSelect count]&gt;0)theRecord = [clientsSelect objectAtIndex:rowIndex]; <br />		case 1:if([animauxSelect count]&gt;0)theRecord = [animauxSelect objectAtIndex:rowIndex]; <br />	}<br />	theValue=[theRecord objectForKey:[aTableColumn identifier]];//ATTENTION COLUMN IDENTIFIER DOIT ETRE EGAL AU NOM DE LA COLONNE DE LA TABLE soit col1 col2... col5<br />	<br />	return theValue;<br />}<br />
    


    C'est une méthode datasource d'une tableview, quasi copié-collé, pas de init sur le "theValue"... Excès de zèle de Clang ?

    2) C'est quoi un "Dead assignement" ?
    3) Un Leak je vois, un Leak of returned object c'est le coup de l'autorelease juste avant le return j'imagine.

    Merci
  • zoczoc Membre
    octobre 2009 modifié #33
    dans 1256666015:

    1°) Uninitialized recever, sur : "theValue=[theRecord..."

    C'est une méthode datasource d'une tableview, quasi copié-collé, pas de init sur le "theValue"... Excès de zèle de Clang ?
    .
    Non. Clang ne peut pas savoir que ton [aTableView tag] ne peut retourner que 0 ou 1, et donc effectivement s'il vaut 2, theRecord n'est pas initialisé. Il manque un "default:" au switch...

    Edit: De plus, si dans tes case la condition du if est fausse, tu te retrouves avec theRecord non initialisé...

    Edit2: Enfin, ton switch, c'est n'importe quoi, il manque des "break" AMHA...

    3) Un Leak je vois, un Leak of returned object c'est le coup de l'autorelease juste avant le return j'imagine.

    un autorelease tout seul, ca fera planter l'application... puisque objectAtIndex ne fait pas de retain sur l'objet qu'il retourne.

    la bonne manière de l'écrire, c'est return [[theValue retain] autorelease];
  • chaps31chaps31 Membre
    21:24 modifié #34
    pas de break, pas de break... ho... c'est ça de modifier des vieux codes, merci...
  • AliGatorAliGator Membre, Modérateur
    21:24 modifié #35
    Oui, c'est là  qu'on voit que l'intégration de Clang/LLVM dans Xcode 3.2 est quand même super puissante, puisque là  où juste l'outil Clang (en ligne de commande ou intégré dans ClangGUI, puisque ce sont les mêmes rapports générés) indique une ligne où se trouve l'erreur, dans Xcode 3.2 tu aurais eu des flèches partout indiquant le pourquoi du comment. Donc indiquant que le "uninitialized receiver" arrivait dans le cas où tu passais par la déclaration "id theRecord" puis que dans le switch tu ne passais par aucun cas, et sortait de là  avec une valeur donc non initialisée ;)
    Ca n'a l'air de rien, mais c'est quant même 'achement bien je trouve avec l'intégration Xcode 3.2 ;)

    Sinon, pourquoi ne pas écrire ton code ainsi ?
    NSArray* theSelect = ([aTableView tag]==0) ? clientsSelect : animauxSelect;<br />id theRecord = ([theSelect count]&gt;0) ? [theSelect objectAtIndex:rowIndex] : nil;<br />return [theRecord objectForKey:[aTableColumn identifier]];
    
  • ClicCoolClicCool Membre
    octobre 2009 modifié #36
    dans 1256673021:
    .../...
    Ca n'a l'air de rien, mais c'est quant même 'achement bien je trouve avec l'intégration Xcode 3.2 ;)

    Je plussoie allègrement.

    Je suis bluffé par Clang et son analyse intégrée à  Xcode :o. (j'ai bon là , sur la casse, Schlum ?)

    Bon, il ne sera pas capable (pour l'instant) de nous alerter d'une iVar qu'on aurait oublié de releaser dans un dealloc, mais c'est déjà  un super "nétoyage" qu'il nous offre là Â  :)
  • schlumschlum Membre
    21:24 modifié #37
    La casse est bonne, mais vous commencez à  me faire envie avec votre intégration que je peux même pas installer sur ma machine  :'( ;D

    Pas grave, je vais tenter de m'auto-persuader que je suis suffisamment propre pour ne pas en avoir besoin  :)
  • chaps31chaps31 Membre
    21:24 modifié #38
    J'ai Xcode 3.2... MacBookPro late 2008 avec Snow leopard, mais je ne vois pas tes flèches...

    Je reprend du code un peu ancien et en effet il y a un peu de boulot... ;)
  • 21:24 modifié #39
    En effet, sur le coup Clang m'a bluffé  <3
  • AliGatorAliGator Membre, Modérateur
    21:24 modifié #40
    Sous Xcode 3.2, pour avoir l'analyse statique faite avec Clang, et donc aussi les flèches et tout le toutim, c'est expliqué ici sur le site d'Apple. Tu n'as qu'à  suivre ce qui est indiqué (autrement dit, choisir "Build & Analyze" dans le menu "Build") et tu devrais avoir les flèches directement sans avoir rien d'autre à  faire.

    (Et bien sûr, à  partir du moment où tu as Xcode 3.2, tu n'as plus du tout besoin d'utiliser l'application ClangGUI qui était un projet créé à  l'époque par Mala, avant que Xcode 3.2 ne sorte et en aucun cas relié à  Apple " au cas où tu pensais qu'il fallait encore utiliser ce programme pour voir les flèches dans Xcode)
  • chaps31chaps31 Membre
    octobre 2009 modifié #41
    dans 1256689669:

    (Et bien sûr, à  partir du moment où tu as Xcode 3.2, tu n'as plus du tout besoin d'utiliser l'application ClangGUI qui était un projet créé à  l'époque par Mala, avant que Xcode 3.2 ne sorte et en aucun cas relié à  Apple " au cas où tu pensais qu'il fallait encore utiliser ce programme pour voir les flèches dans Xcode)

    Non, non j'avais bien compris, merci.

    Edit : Par contre ta proposition de code avec les points d'interrogation, je ne la comprend pas... Notament les points d'interrogation...

    Edit : Sinon Xcode donne moins de points que Clang... Notament Clang fort justement me mettait des Leak sur des objets en retour de méthode où il manque l'autorelease, et XCode ne dit rien... Faut dire que pour une raison que j'ignore (je cherche) un autorelease juste avant le return envoie une erreur d'adressage mémoire...
    Sinon il y a un endroit où l'on peut voir la liste ou tout du moins en un coup d'oeil dans quelles classes il y a des erreurs de gestion de la mémoire ?
  • ClicCoolClicCool Membre
    21:24 modifié #42
    dans 1256721215:
    .../...Edit : Par contre ta proposition de code avec les points d'interrogation, je ne la comprend pas... Notament les points d'interrogation....../...up d'oeil dans quelles classes il y a des erreurs de gestion de la mémoire ?


    C'est un test qui renvoi un résultat différent selon que la condition elle même renvoi vrai ou faux:
    id résultat = (&lt;condition&gt;) ? [résultats-si-ooui : résultat-si-non);
    
  • chaps31chaps31 Membre
    21:24 modifié #43
    Tout à  fait élégant, économie de code merci.

    Sinon je viens d'avoir une révélation j'aurais voulu avoir votre avis pour être certain d'avoir bien compris.

    Dans une classe j'ai :
    -(NSMutableArray *)bddReadClients<br />{<br />	NSMutableArray *clientsFromSQL=[[NSMutableArray alloc] initWithArray:[self createTabComplete:@&quot;clients&quot;:@&quot;ORDER BY nom&quot;]];<br />	//[clientsFromSQL autorelease];<br />	return clientsFromSQL;
    


    Dans une autre j'ai ("clients" est une variable NSMutableArray d'instance de la classe, "postG" une instance de la précédente classe):
    clients=[postG bddReadClients];
    


    Si dans la première je met l'autorelease là  où il est en commentaire, paf erreur accès mémoire....
    Soudain une idée : En fait dans ma 2eme classe le fait de ne pas faire d'alloc init entraine sans doute que "clients" pointe sur l'espace mémoire de "clientsFromSQL", donc lors du release PAF erreur d'adresse...
    Fort de cette réflexion  :P  j'ai écris dans la 2eme classe :
    clients=[[NSMutableArray alloc] initWithArray:[postG bddReadClients]];
    

    Et là  le release fonctionne !! Plus d'erreur d'adresse, donc mon raisonnement semble bon, un nouvel espace mémoire est alloué avec l'alloc init et donc on peut faire le release sans problème.
    J'ai bon ?
  • zoczoc Membre
    octobre 2009 modifié #44
    Non  :)

    Voici ce qu'il faut écrire pour respecter les guidelines concernant le nom des messages et la gestion mémoire:

    -(NSMutableArray *)bddReadClients<br />{<br />   NSMutableArray *clientsFromSQL=[[NSMutableArray alloc] initWithArray:[self createTabComplete:@&quot;clients&quot;:@&quot;ORDER BY nom&quot;]];<br />   return [clientsFromSQL autorelease];<br />
    


    Puis:
    clients=[[postG bddReadClients] retain];
    


    Et dans ton 3ème bout de code, tu leaks le NSMutableArray retourné par bddReadClients si tu ne fais pas d'autorelease dans le code de ce message.

    Je vais une nième fois répéter la même chose. En bricolant tu ne t'en sortiras pas. Il y a une et une seule chose à  faire, lire et relire la documentation officielle sur la gestion mémoire, tant que ce n'est pas rentré dans la tête.

  • schlumschlum Membre
    21:24 modifié #45
    Et p'têt lire " Cocoa par la pratique " aussi si ça n'a pas été fait... Euh il s'appelle " Programmation Cocoa sous Mac OS X " maintenant pardon...
  • chaps31chaps31 Membre
    21:24 modifié #46
    dans 1256725442:

    Et p'têt lire " Cocoa par la pratique " aussi si ça n'a pas été fait... Euh il s'appelle " Programmation Cocoa sous Mac OS X " maintenant pardon...


    J'ai et j'ai lu (version 10.5) mais pas énormément d'infos en plus, pour eux l'avenir est au "ramasse-miettes" (en français dasn le texte)
  • schlumschlum Membre
    21:24 modifié #47
    Décevant alors... tu peux lire l'ancienne version  :)
  • chaps31chaps31 Membre
    21:24 modifié #48
    Zoc je vais lire ça (en Anglais pfff..), j'ai bien compris le système (enfin une fois t'avoir lu), mais par curiosité si ce que j'ai réécris n'est pas terrible, au niveau mémoire ça doit être bon quand même non ?

    PS: Je ne dis pas que je veux laisser comme ça, c'est pas curiosité et pour sonder la profondeur de mes lacunes...
  • zoczoc Membre
    21:24 modifié #49
    Comme je l'ai dit, la 3ème version du code (sans autorelease dans le message retournant le NSMutableArray) provoque une fuite de mémoire, et puis faire des copies de copies de tableau, niveau efficacité, c'est pas super super...

    Les 2 premiers bouts de code ensemble (sans l'autorelease ni le retain) doivent effectivement fonctionner, mais ça ne respecte pas les règles et il y a de fortes chances que l'analyse syntaxique de clang râle.
Connectez-vous ou Inscrivez-vous pour répondre.