Soucis avec NSString

pinuspinus Membre
16:25 modifié dans API UIKit #1
Bonsoir,

J'ai un souci avec une variable de type NSString qui est invariablement (c'est le cas de le dire) "invalid":

que je fasse :
NSString *myStr = [NSString stringWithString:@truc];

ou alors
NSString *myStr = [[NSString alloc] initWithString:@truc];

...myStr est tout le temps 'invalid" !?

Les autres membres de la classe se portent comme des charmes..

J'avoue que je ne pige pas dans quel tapis je me prends les pieds...

Une idée ?

Merci !!

Pinus


Réponses

  • Philippe49Philippe49 Membre
    août 2009 modifié #2
    myStr ne serait pas utilisée ailleurs .. macro par exemple dans un fichier importé ?

    ou truc ...

    Doc de initWithString:
    Important: Raises an NSInvalidArgumentException if aString is nil.
  • pinuspinus Membre
    16:25 modifié #3
    A priori rien de tout ça.

    J'ai essayé de déclarer et initialiser une NSURL : pareil.

    Donc ça doit merder plus haut. Comme je ne trouve pas d'info valable sur google, je dégage ma classe et je recommence :-)

    On va bien voir...
  • LexxisLexxis Membre
    16:25 modifié #4
    Essaie tu d'initialiser une variable d'instance ? Si oui est ce le bout de code que tu utilises pour l'initialisation de cette variable ?
  • allianallian Membre
    16:25 modifié #5
    tu as essayé avec un autre nom pour ton instance ?
  • pinuspinus Membre
    16:25 modifié #6
    Bon, j'ai viré la classe et ai tout réécrit, rien à  faire. Je dois avoir une pétouille quelque part. Très étrangement, j'ai ce type de classes un peu partout dans mon appli et n'ai jamais eu le moindre problème. J'ai réécris la classe de manière basique :
    <br />#import &lt;Foundation/Foundation.h&gt;<br /><br /><br />@interface DataDevNote : NSObject {<br />	NSString *bugID;<br />	NSString *note;<br />	NSString *baseURL;<br />}<br />@property(nonatomic, copy) NSString *bugID;<br />@property(nonatomic, copy) NSString *note;<br />@property(nonatomic, copy) NSString *baseURL;<br />@end<br />
    


    puis :
    <br />#import &quot;DataDevNote.h&quot;<br /><br />@implementation DataDevNote<br />@synthesize bugID;<br />@synthesize note;<br />@synthesize baseURL;<br /><br />-(id)init{<br />	NSURL *m_url;<br />	<br />	m_url = [NSURL URLWithString:self.baseURL];<br />	<br />	return self;<br />}<br />@end<br />
    

    la classe est instanciée et utilisée comme suit :
    <br />...<br />DataDevNote *myDevNote = [DataDevNote alloc];<br />	myDevNote.bugID = self.bugID;<br />	myDevNote.note = self.aNote;<br />	myDevNote.baseURL = @&quot;http://www.XXXXX.com/repert/repert/monscript.php&quot;;<br />	[myDevNote init];<br /><br />...<br />
    


    Perdu je suis... ;-)  Merci de votre aide !!
  • Philippe49Philippe49 Membre
    16:25 modifié #7
    C'est ta méthode init qui pose problème.

    -(id) init {<br />&nbsp; &nbsp; self=[super init];<br />&nbsp; &nbsp; if(self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // les initialisations éventuelles<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}
    



    A noter que l'on peut faire aussi des initialisations dans d'autres méthodes comme -(void)awakeFromNib où l'on est sur que la totalité des xib sont désarchivés.
  • Philippe49Philippe49 Membre
    août 2009 modifié #8
    De plus, il faut appeler init avant de renseigner les variables.

    dans 1251188444:

    la classe est instanciée et utilisée comme suit :
    <br />...<br />DataDevNote *myDevNote = [DataDevNote alloc];<br />	myDevNote.bugID = self.bugID;<br />	myDevNote.note = self.aNote;<br />	myDevNote.baseURL = @&quot;http://www.XXXXX.com/repert/repert/monscript.php&quot;;<br />	[myDevNote init];<br /><br />...<br />
    



    Il faut commencer par  DataDevNote *myDevNote = [[DataDevNote alloc] init];
    puis affecter les valeurs aux properties myDevNote.bugID = self.bugID; ...

  • Philippe49Philippe49 Membre
    16:25 modifié #9
    En résumé, créer l'instance ainsi

    <br />&nbsp; &nbsp; &nbsp; DataDevNote *myDevNote = [[DataDevNote alloc] init];<br />&nbsp; &nbsp; &nbsp; myDevNote.bugID = self.bugID; <br />&nbsp; &nbsp; &nbsp; ...<br />
    


    et à  priori tu n'as pas besoin de redéfinir la méthode init, puisque les initialisations sont faites à  la création de l'instance dans le code ci-dessus.
  • pinuspinus Membre
    16:25 modifié #10
    dans 1251188795:

    C'est ta méthode init qui pose problème.

    -(id) init {<br />&nbsp; &nbsp; self=[super init];<br />&nbsp; &nbsp; if(self) {<br />&nbsp; &nbsp; &nbsp; &nbsp; // les initialisations éventuelles<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}
    



    A noter que l'on peut faire aussi des initialisations dans d'autres méthodes comme -(void)awakeFromNib où l'on est sur que la totalité des xib sont désarchivés.


    Malheureusement, ça ne fonctionne pas mieux, impossible d'initialiser quelque variable que ce soit. C'est vraiment très bizarre car j'ai des classes semblables, instanciées de la même façon, qui ne posent aucun problème.

    pinus
  • Philippe49Philippe49 Membre
    16:25 modifié #11
    dans 1251190987:

    C'est vraiment très bizarre car j'ai des classes semblables, instanciées de la même façon, qui ne posent aucun problème.

    Sans doute qu'elles héritent directement de NSObject, auquel cas [super init] se contente de renvoyer self.
  • pinuspinus Membre
    16:25 modifié #12
    dans 1251191586:

    dans 1251190987:

    C'est vraiment très bizarre car j'ai des classes semblables, instanciées de la même façon, qui ne posent aucun problème.

    Sans doute qu'elles héritent directement de NSObject, auquel cas [super init] se contente de renvoyer self.

    En fait je viens de m'apercevoir que xCode ciblait "Simulator 3.0 Release" et non "Simulator 3.0 debug". En remettant sur "Debug", tout est rentré dans l'ordre..
    Je suis resté collé là  dessus pendant 5 heures : Il me reste beaucoup, beaucoup à  apprendre.

    Merci pour votre aide précieuse !!

    pinus
  • Philippe49Philippe49 Membre
    16:25 modifié #13
    Cela devrait marcher sur release aussi ..
  • Fallout88Fallout88 Membre
    16:25 modifié #14
    Une question, tu n'aurais pas "'invalid" d'afficher lors du survole de ta variable en mode debug? Si c'est le cas cela m'arrive souvent et pour être sûr d'avoir le bon contenu tu tapes dans la console de debug "po nomDeTaVariable" et ce n'est pas pour ça que ta variable ne fonctionne pas. Tu as essayé d'afficher ton texte dans un Text Field?
  • pinuspinus Membre
    16:25 modifié #15
    dans 1251192603:

    Une question, tu n'aurais pas "'invalid" d'afficher lors du survole de ta variable en mode debug? Si c'est le cas cela m'arrive souvent et pour être sûr d'avoir le bon contenu tu tapes dans la console de debug "po nomDeTaVariable" et ce n'est pas pour ça que ta variable ne fonctionne pas. Tu as essayé d'afficher ton texte dans un Text Field?


    Une fois de retour en mode debug, tout est OK. Lorsque je survole les variables, je n'ai plus "invalid". Pour le mode release (je ne savais pas j'avais quitté le mode debug), en effet cela fonctionnait peut-être, mais je ne voyais rien dans le debuger: c'est peut-être normal ?
  • Philippe49Philippe49 Membre
    16:25 modifié #16
    Attention, en C et donc en Objective-C, ce n'est pas parce que cela marche une fois, que cela est correct. Je t'encourage donc à  faire des initialisations d'instances selon le processus habituel.

    Exemple : Je sais d'expérience sur ma machine que le code C va écrire b=2009 parce que la variable b va être allouée juste après a.
    <br />#include &lt;stdio.h&gt;<br /><br /><br />int main(void) {<br />	int a=2008,b;&nbsp; &nbsp; &nbsp; &nbsp;  // les adresses de a et b sont indéterminées<br />	*(&amp;a+1)=a+1;&nbsp; &nbsp; &nbsp;  // on écrit à  l&#39;adresse du int qui suit a<br />	printf(&quot;%d&#092;n&quot;,b);&nbsp; &nbsp; // écrira b=2009<br />	return 0;<br />}
    
  • pinuspinus Membre
    16:25 modifié #17
    dans 1251194609:

    Attention, en C et donc en Objective-C, ce n'est pas parce que cela marche une fois, que cela est correct. Je t'encourage donc à  faire des initialisations d'instances selon le processus habituel.

    Exemple : Je sais d'expérience sur ma machine que le code C va écrire b=2009 parce que la variable b va être allouée juste après a.
    <br />#include &lt;stdio.h&gt;<br /><br /><br />int main(void) {<br />	int a=2008,b;&nbsp; &nbsp; &nbsp; &nbsp;  // les adresses de a et b sont indéterminées<br />	*(&amp;a+1)=a+1;&nbsp; &nbsp; &nbsp;  // on écrit à  l&#39;adresse du int qui suit a<br />	printf(&quot;%d&#092;n&quot;,b);&nbsp; &nbsp; // écrira b=2009<br />	return 0;<br />}
    


    Oui, je vais réécrire ça au propre, car je ne suis pas rassuré. Cela dit, ce n'est pas une appli qui a vocation à  être distribuée. C'est un projet "prétexte" pour apprendre..
  • AliGatorAliGator Membre, Modérateur
    16:25 modifié #18
    Raison de plus pour faire les choses bien et apprendre les bonnes pratiques dès le début !!

    Pour info si tu tapes "init" puis la touche <esc> dans Xcode, il va te proposer de t'insérer un modèle tout prêt pour la méthode init. (vive les TextMacros). Et au moins ce modèle est formaté proprement avec la bonne façon de faire une méthode init.
  • Fallout88Fallout88 Membre
    16:25 modifié #19
    Pour info aussi, l'utilisation de [maClasse alloc] init] peut être remplacer par un [maClasse new] qui à  exactement le même fonctionnement mais je trouve ça plus "propre" (merci Mala)
Connectez-vous ou Inscrivez-vous pour répondre.