[NSCFString count]: selector not recognized

muqaddarmuqaddar Administrateur
20:55 modifié dans Vos applications #1
Salut,

Je veux afficher le contenu d'un array ds une tableView, ce que j'ai déjà  fait 100 fois...

Lorsque que je fais un count sur mon array il me renvoie :
[_calculatedArray count] : 6
ce qui est exact.

En revanche, il bronche dans :
- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
return [_calculatedArray count];
}

Lorsque je lance le programme, j'ai droit à  :
*** -[NSCFString count]: selector not recognized [self = 0x30d090]

Mon array est une variable d'instance qui comprends 4 dico.

Une idée pour me mettre sur la voie ?  :)beta:

Réponses

  • ChachaChacha Membre
    20:55 modifié #2
    dans 1121360985:

    Une idée pour me mettre sur la voie ?  :)beta:

    Oui, mais ça ne va pas être agréable.
    Tu as tous les symptômes d'une mémoire corrompue : la méthode count n'est pas envoyée au bon objet. C'est dû à  une erreur de programmation quelque part ailleurs. ça peut arriver si tu as fait un release de trop, ou plus vicelard, si tu accèdes à  une donnée qui a été autoreleasée mais dont tu as gardé l'adresse.
    Désolé, faut chercher.

    +
    Chacha
    (qui a déjà  eu mille fois un tel problème)
  • muqaddarmuqaddar Administrateur
    20:55 modifié #3
    Pourtant, quand je fais un NSLog de mon array tout est nikel, donc si il bronche pour remplir la tableView, il devrait aussi broncher pour s'afficher dans le NSLog non ?
  • ChachaChacha Membre
    20:55 modifié #4
    dans 1121366668:

    Pourtant, quand je fais un NSLog de mon array tout est nikel, donc si il bronche pour remplir la tableView, il devrait aussi broncher pour s'afficher dans le NSLog non ?

    À partir du moment où la mémoire est corrompue, le comportement est erratique; y'a des trucs qui marchent, et d'autres pas. Mais on ne peut se fier à  rien.
    J'ajoute que ce n'est pas forcément le tableau qui a été trop releasé, ce peut être une tout autre variable.
  • muqaddarmuqaddar Administrateur
    20:55 modifié #5
    Ok, je vais fouiller dans les dico de mon tableau...
    Les dico sont autoreleasés, mais normalement ils ne sont plus adressés ?
  • ChachaChacha Membre
    20:55 modifié #6
    dans 1121368047:

    Ok, je vais fouiller dans les dico de mon tableau...
    Les dico sont autoreleasés, mais normalement ils ne sont plus adressés ?

    Un exemple de code foireux :
    <br />NSArray* array = [[NSArray alloc] init];<br />//array contient, disons, l&#39;adresse 0x123456<br />[array count];//count est envoyé à  l&#39;adresse 0x123456<br />[array release];<br />//array contient toujours l&#39;adresse 0x123456, mais cette zone mémoire est maintenant invalide<br />[array count];//plantage ? peut-être... incorrect, ça c&#39;est sûr<br />
    


    Le problème, c'est qu'avec les variables autoreleasées, on voit moins bien où on a fait des erreurs...
    Exemple plus subtil d'erreur :
    <br />NSString* chaine = [[NSString alloc] initWithString:@&quot;pouf&quot;];<br />NSDictionary* dico = [[NSDictionary alloc] initWithObjectsAndKeys:<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  chaine, @&quot;key1&quot;, @&quot;tutu&quot;, @&quot;key2&quot;, nil];<br />[chaine release];//ok, chaine est retained dans le dico<br />[chaine length];//ok<br />id objet = [dico objectForKey:@&quot;key1&quot;];<br />//objet contient l&#39;adresse de chaine, disons 0x123456<br />[objet length]//ok<br />[dico release];//le dico est releasé, comme son contenu!<br />[objet length];//kaput ! objet contient toujours 0x123456, mais c&#39;est maintenant invalide<br />
    


    +
    Chacha
  • 20:55 modifié #7
    Connaissant oxitan, je verrais aussi un truc dans le genre:
    NSArray* array = [[NSArray alloc] init];<br />array = [NSArray array]; //le pointeur pointe vers un objet autoreleasé, l&#39;objet initial est toujours en mémoire, mais plus rien ne pointe sur lui.
    


    Tu le fais dans -numberOfRowsInTableView: ton NSLog?
  • muqaddarmuqaddar Administrateur
    juillet 2005 modifié #8
    dans 1121371703:

    Connaissant oxitan, je verrais aussi un truc dans le genre:
    NSArray* array = [[NSArray alloc] init];<br />array = [NSArray array]; //le pointeur pointe vers un objet autoreleasé, l&#39;objet initial est toujours en mémoire, mais plus rien ne pointe sur lui.
    


    Tu le fais dans -numberOfRowsInTableView: ton NSLog?



    ça doit pas être bien loin :

    _calculatedVins = [[NSArray alloc] init];<br />_calculatedVins = [self calculateArray];<br />
    


    et dans la méthode "calculateArray" qui retourne un array :

    <br />retArray = [NSMutableArray array];<br />return retArray;<br />
    


    Voilà . Où est la couille du potage ?

    [EDIT]
    J&#39;ai fait ça :<br />_calculatedVins = [[NSArray arrayWithArray:[self calculateArray]] retain];
    


    Et ça marche. Mais je ne trouve pas cela glorieux... y'a pas mieux ?
  • 20:55 modifié #9
    La méthode calculateArray renvoie un tableau qui a été créé en son sein, et qui sera viré de la mémoire dès que  l'occasion se présente (car créé avec +array), Dans la méthode principale tu attribues une nouvelle adresse à  ce pointeur, qui pointera sur rien, vu le que le 'nouveau tableau' sera viré. Donc la (une) solution est que _calculatedVins soit de type NSMutableArray, et que tu fasses ceci:
    _calculatedVins = [[NSMutableArray alloc] init];<br />[_calculatedVins setArray:[self calculateArray]];
    
  • juillet 2005 modifié #10
    dans 1121372710:

    [EDIT]
    J&#39;ai fait ça :<br />_calculatedVins = [[NSArray arrayWithArray:[self calculateArray]] retain];
    



    Ceci aussi:
    [_calculatedVins release];<br />_calculatedVins = [[self calculateArray] retain];
    


    Mais comme tu as visiblement des problèmes avec la gestion de la mémoire, il vaut mieux éviter de créer (et "retainer") des instances de tous les côtés.
  • muqaddarmuqaddar Administrateur
    20:55 modifié #11
    Oui, j'ai toujours des problèmes avec la gestion de la mémoire. Pourtant j'ai lu ces tutos plusieurs fois...  ???

    Ta première solution me semble la plus élégante, puisque je viens de lire que setArray ne fait pas d'autorelease, comme arrayWithArray, et qu'elle absorbe le contenu du tableau en argument,, en faisant un retain et en releasant les objets de l'ancien tableau. C'est ça ?

    Merci aussi à  chacha pour ses conseils.
  • 20:55 modifié #12
    Euh, tu compares deux choses qui sont pas comparables (la seule chose comparable est l'argument de ces 2 méthodes):
    +arrayWithArray: est une méthode de classe de NSArray, qui crée une nouvelle instance qui a pour contenu celui du tableau placé en argument
    -setArray: est une méthode d'instance de NSMutableArray (ce qui suppose que l'instance est déjà  créée), qui vide un mutableArray, et remplace son contenu par celui du tableau placé en argument.
  • muqaddarmuqaddar Administrateur
    20:55 modifié #13
    Ok, merci Renaud.

    ça me semble plus clair maintenant. ;)
Connectez-vous ou Inscrivez-vous pour répondre.