Curiosité NSString

chaps31chaps31 Membre
17:43 modifié dans API AppKit #1
Juste une question par curiosité :
Je viens de découvrir avec un "if" que l'on ne peut pas comparer 2 NSString  avec "==" mais qu'il faut utiliser isEqual comment cela se fait-il, bizarre quand même l'objective-c  ;)
«1

Réponses

  • schlumschlum Membre
    17:43 modifié #2
    dans 1206911402:

    Juste une question par curiosité :
    Je viens de découvrir avec un "if" que l'on ne peut pas comparer 2 NSString  avec "==" mais qu'il faut utiliser isEqual comment cela se fait-il, bizarre quand même l'objective-c  ;)


    Pas isEqual, mais isEqualToString...
    ça n'a rien de bizarre, c'est de la programmation objet.
    Si tu fais "==" tu compares les adresses ; ça ne veut rien dire.
  • AliGatorAliGator Membre, Modérateur
    17:43 modifié #3
    Et cette "bizarrerie" comme tu dis ne viens pas de l'Objective-C à  proprement parler, mais du C lui-même.

    Le "==" ne permet que de comparer des données atomiques, cà d des types "C" standard : int, char, bool, long, ...
    Si tu fais un "==" sur des "int *" ou des "char *" en C, ça ne va que comparer les pointeurs, pas les données.
    Et comme en Objective-C, tout est pointeur (NSString* par exemple)... avec un "==" tu vérifies que c'est le même objet exactement (par exemple pour comparer si un outlet reçu en paramètre est tel ou tel autre outlet, mais sinon c'est plutôt rare), ce qui n'est pas la même chose que de comparer si les deux objets ont le même contenu.

    C'est d'ailleurs plus parlant en prenant de NSMutableStrings :
    NSMutableString* a = [NSMutableString stringWithFormat:@&quot;%@%@&quot; , @&quot;abc&quot; , @&quot;def&quot;]; // donne &quot;abcdef&quot;<br />NSMutableString* b = @&quot;abc&quot;;<br />[b appendString: @&quot;def&quot;];<br />NSMutableString* c = [a retain];
    
    Ici a et b sont deux objets distrincts, mais il se trouve qu'ils représentent une chaà®ne qui est la même. Alors que a et c sont exactement les mêmes objets.
    Ainsi [tt](a == c)[/tt] est vrai, mais [tt](a == b)[/tt] est faux. Alors que, à  ce stade du code, [tt][a isEqualToString:b][/tt] est vrai.
    Par contre, si on modifie par la suite l'objet a ([tt][a appendString:@zzz][/tt] par ex.), Les variables a et c, qui pointent vers le même objet, représenteront tous deux la chaà®ne "abcdefzzz", puisqu'ils pointent toujours sur le même objet, alors que la variable b restera inchangée et représentera la chaà®ne "abcdef". Et du coup à  ce stade du code [tt][a isEqualToString:b][/tt] devient faux. (Alors que [tt][a isEqualToString:c][/tt] est vrai puisque a et c étant le même objet, cela revient à  écrire [tt][a isEqualToString:a][/tt] ;)
  • chaps31chaps31 Membre
    17:43 modifié #4
    Très clair, je vous remercie tout les 2, en venant du PHP non POO, il est vrai que j'oubli de temps en temps que je ne manipule que des pointeurs, au passage j'ai lu que si l'on est certain que l'on compare 2 chaà®nes de caractères (ce qui est mon cas) il vaut mieux utiliser isEqual que isEqualToString, votre avis ?
    Au passage du coup j'avais fais une faute de frappe et écris "isEqualTo" qui marche aussi...
  • schlumschlum Membre
    mars 2008 modifié #5
    "isEqualToString" est plus propre... Et au moins renverra une erreur ou un warning à  la compilation en cas de mauvaise utilisation.

    Et puis en plus, c'est le contraire :
    When you know both objects are strings, this method is a faster way to check equality than isEqual:.
      :P
  • JekarJekar Membre
    17:43 modifié #6
    J en profite que vous parliez de NSString.
    Comment mettre un Char dans un NSString???
  • schlumschlum Membre
    17:43 modifié #7
    dans 1206976701:

    J en profite que vous parliez de NSString.
    Comment mettre un Char dans un NSString???


    On lit la doc  :P

    + (id)stringWithUTF8String:(const char *)bytes<br />+ (id)stringWithCString:(const char *)cString encoding:(NSStringEncoding)enc<br />- (id)initWithUTF8String:(const char *)bytes<br />- (id)initWithCString:(const char *)nullTerminatedCString encoding:(NSStringEncoding)encoding<br />- (id)initWithBytes:(const void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding<br />- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length encoding:(NSStringEncoding)encoding freeWhenDone:(BOOL)flag
    


    Pour la doc, je te conseille AppKiDo
  • JekarJekar Membre
    17:43 modifié #8
    desole, j ai eu beau cherche, j ai pas trouve  >:)

    Merci  :p
  • schlumschlum Membre
    17:43 modifié #9
    dans 1206979432:

    desole, j ai eu beau cherche, j ai pas trouve  >:)

    Merci  :p


    Alors télécharge AppKiDo vite fait bien fait...
  • JekarJekar Membre
    17:43 modifié #10
    je l'ai en plus  :o
  • JekarJekar Membre
    mars 2008 modifié #11
    Bon, je suis mauvais, pourquoi ca marche pas ce petit code?
    <br />        char saisie;<br />	NSString *texte = [NSString alloc] ;<br />	scanf( &quot;%c&quot;, &amp;saisie );<br />	[texte initWithCString:saisie];
    


  • AliGatorAliGator Membre, Modérateur
    17:43 modifié #12
    Sans doute parce qu'il attend une "CString" autrement dit un "(const) char*" avec un terminateur "\0" au bout.
    Et toi tu lui donnes un "char" tout court et sans terminateur.

    char saisie[2]; // un tableau de deux caractères (= une chaà®ne d&#39;un caractère + terminateur)<br />saisie[1] = 0; // d&#39;ailleurs le voilà  le terminateur, il faut bien le mettre !<br />NSString *texte = [NSString alloc];<br />scanf( &quot;%c&quot;, saisie ); // ou &amp;(saisie[0]) si tu trouves ça plus clair, mais plus besoin de &amp;saisie (vu que now saisie est un &quot;char*&quot;)<br />[texte initWithCString:saisie]; // et en plus comme ça ça devrait compiler puisque tu passes un char* et plus un char tout-court
    
  • Philippe49Philippe49 Membre
    17:43 modifié #13
    dans 1206998070:

    Pourquoi ca marche pas ce petit code?
    <br />&nbsp; &nbsp; &nbsp; &nbsp; char saisie;<br />	NSString *texte = [NSString alloc] ;<br />	scanf( &quot;%c&quot;, &amp;saisie );<br />	[texte initWithCString:saisie];
    



    ou bien  [texte initWithFormat:@%c,saisie];

    identique au C :
    char chaine[20];
    sprintf(chaine,"%c",saisie);





  • chaps31chaps31 Membre
    avril 2008 modifié #14
    Je sorts un peu du sujet mais traite toujours des chaà®ne de caractères, j'essaie d'éviter de créer trop de sujets.

    Juste une question simple, comment faire pour afficher les caractères non ASCII é,à ,è...  ?

    Oups je n'avais pas vu les messages précédents, désolé de m'intercaler...
  • schlumschlum Membre
    17:43 modifié #15
    dans 1207069357:

    Je sorts un peu du sujet mais traite toujours des chaà®ne de caractères, j'essaie d'éviter de créer trop de sujets.

    Juste une question simple, comment faire pour afficher les caractères non ASCII é,à ,è...  ?

    Oups je n'avais pas vu les messages précédents, désolé de m'intercaler...


    On utilise le fichier de chaà®nes localisées... Mais c'est une question qui a déjà  été posée 1000 fois ici  :P
  • AliGatorAliGator Membre, Modérateur
    17:43 modifié #16
    dans 1207071791:

    dans 1207069357:

    Je sorts un peu du sujet mais traite toujours des chaà®ne de caractères, j'essaie d'éviter de créer trop de sujets.

    Juste une question simple, comment faire pour afficher les caractères non ASCII é,à ,è...  ?

    Oups je n'avais pas vu les messages précédents, désolé de m'intercaler...


    On utilise le fichier de chaà®nes localisées... Mais c'est une question qui a déjà  été posée 1000 fois ici  :P
    Pour t'aider à  orienter tes recherches, cherche dans la doc ou sur les forums NSLocalizedString.

    En gros faut mettre tes chaà®nes dans des fichiers (au format texte et encodés en UTF-8) à  côté de ton appli, et c'est là  dedans que tu vas piocher tes constantes de chaà®nes. Comme ça tu es sûr que c'est :
    - indépendant de ton code source, plus logique que mettre tout en dur
    - utilisant le bon encodage de caractères, donc permettant aussi de gérer les caractères >127 genre accents, etc
    - et en plus ça permet (et c'est aussi l'intérêt premier à  la base) de faire des fichiers dépendants de la langue (un fichier de chaà®ne par langue dans laquelle tu vas traduire ton appli à  la fin)
  • chaps31chaps31 Membre
    avril 2008 modifié #17
    Merci je vais potasser NSLocalizedString.

    ......

    EDIT : OK, j'ai compris créer le fichier .string remplir de "remplacepar"="ma chaine avec des é" et voilà .
    Mais pas très pratique, en l'occurence je n'ai pas de chaine constante il s'agit de récupérer des chaines de NSTextField, en gros quand l'utilisateur va taper un é è ê à  ô... je veux que ça soit bien enregistré (envoie à  une base de donnée) avec le NSLocalizedString ça ne m'a pas l'air possible vu qu'il s'agit si j'ai bien compris de chaines pré-enregistrés, donc je ne vois pas trop comment lui dire : quand tu rencontre un é (qu'il ne reconnait pas... donc coment lui présenter le é) remplace par un é (que tu reconnais...).
    J'ai dû louper un truc je le sens
  • chaps31chaps31 Membre
    17:43 modifié #18
    Bon ben là ... je n'y arrive pas, je n'ai pas trouvé les infos ... :-\\

    En effet en premier j'ai des messages d'alerte avec des accents, là  nslocalizedsstring semble approprié (mais je n'ai pas encore trouvé de mode d'emploi clair), mais comment faire pour du texte rentré par l'utilisateur et donc non connu à  priori, comment modifier les é è... pour avoir le bon texte... (avant de l'envoyer à  ma BDD).  :)beta:
  • AliGatorAliGator Membre, Modérateur
    17:43 modifié #19
    Ah ok j'avais pas compris le contexte exact.

    Alors les NSLocalizedString c'est à  utiliser à  la place de mettre des chaà®nes littérales en dur dans ton code.
    Par exemple pour les messages d'alerte que tu pourrais vouloir générer par code, etc.

    Pour récupérer du texte depuis ton interface, il n'y a aucun problème avec les "é" et autres "è".
    Ou plutôt le seul truc c'est qu'il faut faire attention à  ce que tu utilises les mêmes encodages de texte de chaque côté.
    Sachant que les objets graphiques (NSTextField & co) utilisent tous l'encodage UTF-8.

    Donc soit tu migres ta base en UTF8 (c'est un réglage au niveau de ta base de données elle-même en général pour lui dire avec quel encodage de texte stocker les chaà®nes dans la base), soit tu fais la conversion de UTF-8 vers l'encodage utilisé dans ta base (ISO-8859-1 ?), en utilisant les méthodes de NSString (dataUsingEncoding: ou CStringUsingEncoding: par exemple, etc) pour envoyer à  ta base la chaà®ne convertie dans le bon encodage.
  • chaps31chaps31 Membre
    17:43 modifié #20
    o:) o:)
  • chaps31chaps31 Membre
    17:43 modifié #21
    OK, j'ai trouvé, en fait pour accéder à  ma base postgre j'utilise un framework (pgcocoaDB) et c'est à  la sortie de ce framework qu'il y a un problème... arggh.. je n'ai pas le source..; que les h.... Ca va être chaud de trouver l'encodage...
    Merci
  • chaps31chaps31 Membre
    17:43 modifié #22
    Heu... Quelqu'un connait un meilleur framework pour postgre que celui que j'utilise (choisi au pif..) ? B)
  • schlumschlum Membre
    17:43 modifié #23
    dans 1207237368:

    Heu... Quelqu'un connait un meilleur framework pour postgre que celui que j'utilise (choisi au pif..) ? B)


    Si on sait pas celui que tu utilises, on aura du mal...
  • AliGatorAliGator Membre, Modérateur
    17:43 modifié #24
    dans 1207240755:

    dans 1207237368:

    Heu... Quelqu'un connait un meilleur framework pour postgre que celui que j'utilise (choisi au pif..) ? B)


    Si on sait pas celui que tu utilises, on aura du mal...
    Si tu sais pas lire, aussi...  :) :)
    [...]j'utilise un framework (pgcocoaDB)
  • chaps31chaps31 Membre
    17:43 modifié #25
    ;)

    Donc si certains d'entre vous utilise des bases postgre... le framework (pgcocoaDB  ;) )marche mais il y a ce pb d'encodage texte...
  • schlumschlum Membre
    17:43 modifié #26
    Ah, j'ai sauté un post en pensant que c'était un doublon...  ???

    http://sourceforge.net/projects/pgsqlcocoa/
  • chaps31chaps31 Membre
    avril 2008 modifié #27
    Merci,, après décorticage jje trouve pgcocoaDB plus facile à  utiliser, maintenant j'ai toujours ce problème d'encodage, j'ai controlé en effet les "é", "è" et autre "à " sont corrects dans la requête créée par mon code, il prend bien les accents entrés par l'utilisateur, cette requête est alors un argument d'une méthode de pgcocoadb, mais cette méthode mmodifie mon texte visiblement car j'obtiens :

    [glow=yellow,2,300]Connected to database MaDataBase on 2008-04-04 12:55:24 +0200.
    PostgreSQL Error: ERROR:  invalid byte sequence for encoding "UTF8": 0x8e
    HINT:  This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
    [/glow]

    OK, ce n'est plus vraiment un problème cocoa, mais vous savez à  quoi correspond le 0x8e ? Je ne vois pas quel type d'encodage est utilisé...
  • chaps31chaps31 Membre
    avril 2008 modifié #28
    Bon, même si je n'ai toujours pas résolu mon problème d'accents dasn les requêtes de ma base j'ai essayé d'utiliser Localizedstring pour mes messages d'alertes, que eux, déjà  aient des accents.

    J'ai créé sous X-code un fichier vide que j'ai rempli de  :
    [glow=yellow,2,300]"alertOne"="Mon premier message d'alerte avec accents";
    ....[/glow]
    Sauvegardé et mis dans les ressources de mon projet.

    Puis  : [glow=yellow,2,300]NSRunAlertPanel(@Le titre,NSLocalizedString(@alertOne,nil),@OK,nil,nil);[/glow]

    ET là  ça m'affiche... <3   [glow=yellow,2,300]Le titre  alertOne[/glow]  :-\\<br />et pas : [glow=yellow,2,300]Le titre Mon premier message d'alerte avec accents[/glow]  B)

    Je pense qu'il y a un truc que je n'ai pas compris et je ne comprends pas ce que je n'ai pas compris  :P Et comme d'hab' la doc cocoa sur le net c'et pas évident de trouver de bonnes sources (sauf ici  o:)   ;)  )

    EDIT : Ho... Menu File-Make Localizable, je m'empresse de cliquer, "attention cela va modifier ...gnagnagna", même pas peur, et hop je vois qu'il a créé des info.plist ok, je ne sais pas trop ce que c'est et que le projet est localisé en English, heu.. non là  en français, comment je change ça ? Bon pas trouvé... Je lance et... toujours pareil... Ca n'a rien changé...
  • Philippe49Philippe49 Membre
    17:43 modifié #29
    Tu as bien mis l'extension .strings à  ton fichier ?
  • chaps31chaps31 Membre
    17:43 modifié #30
    oui  :-\\

    EDIT : Whaou je suis passé planteur de pousse... ;)
  • Philippe49Philippe49 Membre
    17:43 modifié #31
    Bravo au pousseur de plantes

    Moi je nomme le fichier Localizable.strings

    Dans le menu Build, sélectionne l'option Clean All Targets pour nettoyer les fichiers déjà  compilés.
    Renomme ton fichier
    Build & Run
Connectez-vous ou Inscrivez-vous pour répondre.