ValueForKey et booléen

RocouRocou Membre
05:52 modifié dans API AppKit #1
J'essaie de tester la valeur d'un booléen issu d'une base de données mais je n'y arrive pas.

Voici mon code: ('verifie' est un champ de type booléen)

if ([[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;])<br />			NSLog(@&quot;verifie: %@&quot;,[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;]);


Le programme entre dans le 'if' et affiche 'false'  ???

Réponses

  • FloFlo Membre
    avril 2009 modifié #2
    En fait, il me semble que les types ne dérivant pas de NSObject ne sont encapsulés à  l'aide d'une classe : NSNumber. Donc pour récupérer ce genre de type il faut d'abord récupérer un objet de type NSNmuber et appeler la méthode appropriée, ici boolValue :

    <br />[[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;] boolValue];<br />
    



    Le programme entre dans le 'if' et affiche 'false'


    C'est normal, tout comme le if du c, toute valeur différentes de 0 est synonymes de vrai, ici ton un objet NSNumber est renvoyé, c'est différent de 0, donc vrai.

  • FloFlo Membre
    05:52 modifié #3
    De plus, ton NSLog() attend un objet de type NSString et toi tu lui donne un objet de type NSNumber, c'est donc sa méthode description qui est appelée.

    Il faudrait écrire :

    NSLog(@verifie: %i,[[[rs dictionaryFromRecord] valueForKey:@verifie] boolValue]);

  • RocouRocou Membre
    05:52 modifié #4
    dans 1239727269:

    De plus, ton NSLog() attend un objet de type NSString et toi tu lui donne un objet de type NSNumber, c'est donc sa méthode description qui est appelée.

    Il faudrait écrire :

    NSLog(@verifie: %i,[[[rs dictionaryFromRecord] valueForKey:@verifie] boolValue]);


    Merci. J'ai bien compris le principe mais cela ne fonctionne pas (j'obtiens toujours 0). J'imagine que le type booléen est "crypté" d'une façon particulière par PostgreSQL. Je vais creuser de ce côté.
  • NoNo Membre
    05:52 modifié #5
    dans 1239871002:

    J'imagine que le type booléen est "crypté" d'une façon particulière par PostgreSQL. Je vais creuser de ce côté.


    Essai d'afficher le type de classe que renvoie valueForKey:@verifie par le code ci-dessous juste avant ton if :
    <br />id obj=[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;];<br />NSLog(@&quot;instance=%x, classe=%@, description=%@&quot;, obj, [obj className], [obj description]);<br />
    


    avec les quelques renseignements renvoyés par NSLog, ça va permettre de mieux cerner ce mystérieux bool.
  • RocouRocou Membre
    05:52 modifié #6
    dans 1239872475:

    avec les quelques renseignements renvoyés par NSLog, ça va permettre de mieux cerner ce mystérieux bool.

    Merci pour ta patience, alors voici ce que cela donne:

    instance=387b0, classe=NSCFString, description=false
  • FloFlo Membre
    avril 2009 modifié #7

    J'ai bien compris le principe mais cela ne fonctionne pas (j'obtiens toujours 0)


    C'est normal regardes :
    <br />BOOL yes = YES;<br />NSLog(@&quot;%i&quot;, yes);<br />	<br />BOOL no = NO;<br />NSLog(@&quot;%i&quot;, no);<br />
    


    Le premier NSLog() affiche 1 et le deuxième 0. Comme je le disais plus haut, en C et donc en objective-c, dans les if 0=false=NO et 1=true=YES.
  • NoNo Membre
    avril 2009 modifié #8
    dans 1239873163:

    dans 1239872475:

    avec les quelques renseignements renvoyés par NSLog, ça va permettre de mieux cerner ce mystérieux bool.

    Merci pour ta patience, alors voici ce que cela donne:

    instance=387b0, classe=NSCFString, description=false


    Comme ton bool est renvoyé sous forme de chaine valant soit false, soit true.
    Remplace ton if par :
    <br />if ([[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;] isEqualToString:@&quot;true&quot;])<br />{<br />   // mon bool est vrai<br />}<br />
    

  • RocouRocou Membre
    05:52 modifié #9
    dans 1239873442:


    J'ai bien compris le principe mais cela ne fonctionne pas (j'obtiens toujours 0)


    C'est normal regardes :
    <br />BOOL yes = YES;<br />NSLog(@&quot;%i&quot;, yes);<br />	<br />BOOL no = NO;<br />NSLog(@&quot;%i&quot;, no);<br />
    


    Le premier NSLog() affiche 1 et le deuxième 0. Comme je le disais plus haut, en C et donc en objective-c, dans les if 0=false=NO et 1=true=YES.

    Oui, ça j'ai bien compris mais je ne vois pas le rapport avec le NSLog proposé par No qui est censé afficher 0 si le contenu de mon champ est false et 1 s'il est égale à  true.

    J'ai contourné le problème en faisant mon test directement dans ma requête SQL mais c'est une solution provisoire me permettant néanmoins d'avancer. Mais j'aimerais bien comprendre comment interpréter mon champ booléen directement en objective-c.
  • RocouRocou Membre
    05:52 modifié #10
    dans 1239874285:

    dans 1239873163:

    dans 1239872475:

    avec les quelques renseignements renvoyés par NSLog, ça va permettre de mieux cerner ce mystérieux bool.

    Merci pour ta patience, alors voici ce que cela donne:

    instance=387b0, classe=NSCFString, description=false


    Comme ton bool est renvoyé sous forme de chaine valant soit false, soit true.
    Remplace ton if par :
    <br />if ([[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;] isEqualToString:@&quot;true&quot;])<br />{<br />&nbsp;&nbsp; // mon bool est vrai<br />}<br />
    


    Hélas, cela ne change rien, on ne passe jamais dans ce 'if'  :-\\
  • NoNo Membre
    avril 2009 modifié #11
    dans 1239874815:

    Hélas, cela ne change rien, on ne passe jamais dans ce 'if'  :-\\


    Normal, le NSLog que tu as renvoyé retourne la chaine "false", donc le test du if est négatif (puisque je test avec "true").
    Si tu remplaces true par false dans le equalToString:, tu passeras dans ton if.
  • RocouRocou Membre
    avril 2009 modifié #12
    dans 1239874977:

    dans 1239874815:

    Hélas, cela ne change rien, on ne passe jamais dans ce 'if'  :-\\


    Normal, le NSLog que tu as renvoyé retourne la chaine "false", donc le test du if est négatif (puisque je test avec "true").
    Si tu remplaces true par false dans le equalToString:, tu passeras dans ton if.

    ???
    Mais quel est l'intérêt? Que je passe tout le temps dans le if ou pas du tout, ça ne change rien. Il faut que j'y passe ou pas selon la valeur du champ 'verifie' qui est, soit FALSE soit TRUE.
    Ou alors on ne parle pas de la même chose.

    EDIT: Par ailleurs, après test, on ne passe toujours pas dans mon if que je mettre true ou false dans le equalToString:
  • AliGatorAliGator Membre, Modérateur
    05:52 modifié #13
    A mon avis No croyais juste que tu disais "ça passe pas dans le if" parce que tu n'avais testé qu'avec le cas d'une requête en particulier qui se trouvait retourner la chaà®ne "false"... Donc il voulais dire "bah dans ce cas puisque ton champ a la valeur "false" c'est justement normal que tu ne passes pas dans ton if"... il a sans doute imaginé que tu n'avais pas pensé tester avec une requête qui te renvoie "true" comme valeur dans ton champ "verifie", et donc disait "ça passe pas dans mon if" après ne l'avoir testé qu'avec un champ qui se trouvait être "false"...

    Par contre étonnant que [... isEqualToString:@true] ne fonctionne pas pour le coup. Faudrait décomposer ton résultat de valueForKey pour le disséquer. Déjà  on l'a un peu fait avec le NSLog de No, ça semble être une NSCFString (autrement dit une NSString) pourtant... faut vérifier les 2 valeurs possibles (à  priori @true et @false pourtant mais bon) et creuser d'avantage...
  • NoNo Membre
    avril 2009 modifié #14
    Pas mieux que Ali.

    Le résultat du NSLog que je t'ai demandé montre ceci :
    instance=387b0  ->  le pointeur de l'objet semble correct (pas nil),
    classe=NSCFString  -> la classe de l'objet est NSString,
    description=false  -> le contenu de l'objet est la chaine "false".

    Peut être (mais je suppute), que la classe de connexion à  ta base pgsql n'effectue pas une conversion correcte entre le pilote pgsql (qui doit être du C, et donc renvoie les chaines terminées par le caractère 0) et l'objet NSString.

    Fais ce dernier test :
    <br />id obj=[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;];<br />NSLog(@&quot;chaine=&lt;%@&gt;, data=%@&quot;, obj, [obj dataUsingEncoding:NSASCIIStringEncoding]);<br />
    
  • RocouRocou Membre
    05:52 modifié #15
    dans 1239882752:

    Pas mieux que Ali.

    Le résultat du NSLog que je t'ai demandé montre ceci :
    instance=387b0  ->  le pointeur de l'objet semble correct (pas nil),
    classe=NSCFString  -> la classe de l'objet est NSString,
    description=false  -> le contenu de l'objet est la chaine "false".

    Peut être (mais je suppute), que la classe de connexion à  ta base pgsql n'effectue pas une conversion correcte entre le pilote pgsql (qui doit être du C, et donc renvoie les chaines terminées par le caractère 0) et l'objet NSString.

    Fais ce dernier test :
    <br />id obj=[[rs dictionaryFromRecord] valueForKey:@&quot;verifie&quot;];<br />NSLog(@&quot;chaine=&lt;%@&gt;, data=%@&quot;, obj, [obj dataUsingEncoding:NSASCIIStringEncoding]);<br />
    


    Je pense aussi que le problème vient de la classe de connexion.

    Voici ce que ton code donne (systématiquement):

    chaine=<false>, data=<66616c73 65>
  • NoNo Membre
    05:52 modifié #16
    dans 1239883430:

    Je pense aussi que le problème vient de la classe de connexion.
    Voici ce que ton code donne (systématiquement):
    chaine=<false>, data=<66616c73 65>


    Maintenant, je le pense aussi.
    Même si il y a VRAI dans le résultat de données de la base, cela te renvoie la chaine false dans ton programme.
  • RocouRocou Membre
    05:52 modifié #17
    dans 1239883954:

    dans 1239883430:

    Je pense aussi que le problème vient de la classe de connexion.
    Voici ce que ton code donne (systématiquement):
    chaine=<false>, data=<66616c73 65>


    Maintenant, je le pense aussi.
    Même si il y a VRAI dans le résultat de données de la base, cela te renvoie la chaine false dans ton programme.

    Je vais essayer de contacter l'auteur de la classe. En tout cas merci à  tous pour le temps passé, j'ai une fois de plus appris beaucoup de choses.
  • RocouRocou Membre
    05:52 modifié #18
    Youpi! L'auteur de la classe (Andy Satori) à  fait une mise à  jour: tout fonctionne!  :adios!:
Connectez-vous ou Inscrivez-vous pour répondre.