Problème avec le type de base int

2»

Réponses

  • CéroceCéroce Membre, Modérateur
    février 2009 modifié #32
    dans 1235174609:

    Effectivement, tu as raison, [super init] est suffisant. Perso je mets self=[super init]; parce que pour moi cela chante mieux, mais ce n'est pas obligatoire.


    Un peu hors-sujet, mais voici un article sur ce point sur le blog de Wil Shipley:
    http://www.wilshipley.com/blog/2005/07/self-stupid-init.html

    Personnellement, Philippe, je fais comme toi, j'ai conservé la forme idiomatique qu'on trouve depuis le début de Cocoa, même si elle ne me paraà®t plutôt moins naturelle.
  • schlumschlum Membre
    09:40 modifié #33
    dans 1235214599:

    En mettant  - (id)initWithX:(CGFloat) xVal Y:(CGFloat)yVal comme dans CIVector, ça marche, on a bien le 5 et le 1.
    Y a forcément une erreur quelque part, il ne va pas chercher la signature de CIVector pour l'appliquer à  Toto qui hérite de NSObject !


    Si, ça doit être un truc du genre... Il bafouille sur les signatures !
    Dans le fichier préprocessé, celui de CIVector apparaà®t avant l'autre :

    // ...<br />- (id)initWithX:(CGFloat)x;<br />- (id)initWithX:(CGFloat)x Y:(CGFloat)y;<br />- (id)initWithX:(CGFloat)x Y:(CGFloat)y Z:(CGFloat)z;<br />- (id)initWithX:(CGFloat)x Y:(CGFloat)y Z:(CGFloat)z W:(CGFloat)w;<br />// ...<br />- (id)initWithX:(int)_x Y:(int)_y;<br />- (void)printXY;<br />// ...
    
  • Philippe49Philippe49 Membre
    09:40 modifié #34
    On progresse : Comme cela, ça marche mieux

    Toto *t ;
    t=[Toto alloc];
    [t initWithX:5 Y:1];
  • schlumschlum Membre
    09:40 modifié #35
    C'est vrai qu'alloc renvoie un "id"... Du coup, ça fait appel à  "initWithX:Y:" sur "id".
    Mais du coup, pourquoi passe-t-il dans la bonne (avec gdb) ?
  • schlumschlum Membre
    09:40 modifié #36
    Non, chez moi ça ne fonctionne pas mieux du tout...
  • Philippe49Philippe49 Membre
    09:40 modifié #37
    Si moi ça marche :

    #import &lt;Foundation/Foundation.h&gt;<br />#import &lt;Cocoa/Cocoa.h&gt;<br /><br />@interface Toto : NSObject {<br />	int x,y;<br />}<br /><br />- (id) initWithX:(NSInteger) xVal Y:(NSInteger) yVal;<br /><br />@property&nbsp; int x;<br />@property&nbsp; int y;<br /><br />@end<br /><br />@implementation Toto<br /><br />- (id)initWithX:(NSInteger) xVal Y:(NSInteger)yVal<br />{<br />	if((self=[super init])!=nil) {<br />		x = xVal;<br />		y = yVal;<br />			NSLog(@&quot;xVal=%ld , yVal=%ld , x=%ld , y=%ld&quot;,xVal,yVal,x,y); <br />	}<br />	return self;<br />}<br /><br />@synthesize x,y;<br /><br />@end<br /><br />int main (int argc, const char * argv&#91;]) {<br />	Toto *t ;<br />	t=[Toto alloc];<br />	NSLog(@&quot;%@&quot;,[t class]);<br />	[t initWithX:5 Y:1];<br />	NSLog(@&quot;%d,%d&quot;,t.x,t.y);<br />	[t release];<br />	return 0;<br />}<br />
    


    % gcc pgm.m -o pgm -framework Cocoa
    % pgm
    2009-02-21 12:49:59.535 pgm[1337:10b] Toto
    2009-02-21 12:49:59.536 pgm[1337:10b] xVal=5 , yVal=1 , x=5 , y=1
    2009-02-21 12:49:59.537 pgm[1337:10b] 5,1
    %

  • schlumschlum Membre
    09:40 modifié #38
    Ah si ça passe mieux, j'avais changé dans mon fichier .i préprocessé   :o
  • Philippe49Philippe49 Membre
    09:40 modifié #39
    Inquiétant quand même parce qu'à  la sortie du alloc, la classe est bien Toto .
    Cela veut dire que l'imbrication de messages n'est pas équivalente à  la succession des messages. C'est un énorme piège.
  • schlumschlum Membre
    09:40 modifié #40
    Enfin logique tu y vas fort...  :o
    Il n'y a aucune logique là  dedans  :)

    Qu'on l'appelle sur id, qu'il se mélange et rentre dans celle de CIVector, pourquoi pas.
    Mais là  il rentre dans la bonne avec la mauvaise signature, c'est un peu nimp'  :o
  • Philippe49Philippe49 Membre
    09:40 modifié #41
    dans 1235217338:

    Enfin logique tu y vas fort...  :o
    Il n'y a aucune logique là  dedans  :)

    Oui je l'ai retiré depuis.
  • schlumschlum Membre
    février 2009 modifié #42
    int main (int argc, const char * argv&#91;])<br />{<br />	Toto *t = [Toto alloc];<br />	[(CIVector*)t initWithX:5 Y:1];<br />	[t printXY];<br />	[t release];<br />	return 0;<br />}
    


    Il rentre dans le "initWithX:Y" de Toto avec la signature de CIVector... (et on obtient ce qu'on avait avec les deux sur une seule ligne).
    Surprenant je dois dire. Dangereux le dynamisme parfois !

    (et ce code ne produit aucun warning !)
  • schlumschlum Membre
    février 2009 modifié #43
    Enfin j'arrive à  y trouver une certaine logique.
    Cet appel va donner "objc_msgSend((id)t,@selector(initWithX:Y:),5,1)" (5 et 1 seront lus en tant que floats)

    Comme le type de "t" est dans sa structure "objc_class", il va le reconnaà®tre comme "Toto" et va appeler la bonne méthode, mais les arguments vont être mal interprétés.
  • GreensourceGreensource Membre
    09:40 modifié #44
    Et bien je pensais pas que c'était si dangereux (j'ai pas exactement tout saisi).
    Mais alors du coup, si je ne veux plus que cela arrive, n'aurais-je pas intérêt, lors du init de retourner, plutôt qu'un id un Toto?
    Et d'ailleurs cela m'amène à  me poser une autre question (venant de java): pourquoi on ne renvois pas systématiquement le bon type? C'est pour pouvoir faire de la généricité?
  • Philippe49Philippe49 Membre
    09:40 modifié #45
    dans 1235220853:

    Et bien je pensais pas que c'était si dangereux (j'ai pas exactement tout saisi).
    Mais alors du coup, si je ne veux plus que cela arrive, n'aurais-je pas intérêt, lors du init de retourner, plutôt qu'un id un Toto?

    Non, renvoyer (id), c'est pour avoir un comportement correct lorsqu'une classe hérite d'une autre, et que l'on ne redéfinit pas la méthode d'initialisation, ce qui est très souvent le cas.
  • Philippe49Philippe49 Membre
    09:40 modifié #46
    Et sans aller chercher une classe et une méthode presque exotique

    #import &lt;Foundation/Foundation.h&gt;<br /><br />@interface Toto : NSObject {<br />	int x;<br />}<br /><br />- (id) initWithFloat:(NSInteger) xVal;<br /><br />@property&nbsp; int x;<br /><br />@end<br /><br />@implementation Toto<br /><br />- (id)initWithFloat:(NSInteger) xVal <br />{<br />	self=[super init];<br />	if(self != nil) {<br />		x = xVal;<br />	}<br />	return self;<br />}<br /><br />@synthesize x;<br /><br />@end<br /><br />int main (int argc, const char * argv&#91;]) {<br />	Toto *t ;<br />	t=[[Toto alloc] initWithFloat:5];<br />//	t=[Toto alloc];<br />//	NSLog(@&quot;%@&quot;,[t class]);<br />//	[t initWithFloat:5];<br />	NSLog(@&quot;%d&quot;,t.x);<br />	[t release];<br />	return 0;<br />}
    


    provoque l'écriture sans aucun Warning de

    % gcc pgm2.m -o pgm -framework Foundation
    % pgm
    2009-02-21 16:15:39.704 pgm[1670:10b] 1084227584
    %


    alors que naturellement la partie décommentée fonctionne bien ...
  • Philippe49Philippe49 Membre
    09:40 modifié #47
    La synthèse :

    Avant d'utiliser le schéma [[UneClasse alloc] initWithMachin:unArgument];  il faut être sur qu'aucune autre classe ne définit une méthode initWithMachin: avec un argument différent de celui utilisé dans la méthode de UneClasse.

    Si néammoins on veut garder initWithMachin: , séparer en deux phases
            t=[uneClasse alloc] suivi de [t initWithMachin:unArgument];
    ou caster en
            t=[(UneClasse*) [UneClasse alloc] initWithMachin:unArgument];
  • GreensourceGreensource Membre
    09:40 modifié #48
    Ok, je ferais attention à  ça la prochaine fois. Mais c'est balèze de trouver si une méthode à  déjà  le même nom! J'aurais jamais réussi à  trouver tout seul celle que vous avez trouvé.
  • mpergandmpergand Membre
    09:40 modifié #49
    J'ai trouvé ça:
    http://www.cocoabuilder.com/archive/message/cocoa/2005/6/22/139644

    Dans XCode 3, j'ai rajouté -Wstrict-selector-match dans Other Warning Flags et bingo !

    Line Location AppController.m:61: warning: multiple methods named '-initWithX:Y:' found
    Line Location CIVector.h:45: warning: using '-(id)initWithX:(CGFloat)x Y:(CGFloat)y'
    Line Location ClasseEssai.h:22: warning: also found '-(id)initWithX:(int)x Y:(int)y'

  • Philippe49Philippe49 Membre
    09:40 modifié #50
    dans 1235291921:

    Ok, je ferais attention à  ça la prochaine fois. Mais c'est balèze de trouver si une méthode à  déjà  le même nom! J'aurais jamais réussi à  trouver tout seul celle que vous avez trouvé.


    Aucune difficulté : Tu tapes intWithX: dans le search field de la doc ... en faisant les réglages  nécessaires. La lecture de la documentation est essentielle avec Objective-C.
  • GreensourceGreensource Membre
    09:40 modifié #51
    Ah bas oui je suis bête. J'avais oublier que les méthodes apparaissaient aussi dans la doc! Elle est trop génial celle là  quand je compare au reste n'empêche!
  • ChachaChacha Membre
    09:40 modifié #52
    dans 1235294806:

    Ah bas oui je suis bête. J'avais oublier que les méthodes apparaissaient aussi dans la doc! Elle est trop génial celle là  quand je compare au reste n'empêche!

    Encore plus simple :
    Option+double clic      sur le nom d'une méthode ouvre la doc associée
    Command+double clic sur le nom d'une méthode permet de s'y téléporter
  • schlumschlum Membre
    09:40 modifié #53
    dans 1235294806:

    Ah bas oui je suis bête. J'avais oublier que les méthodes apparaissaient aussi dans la doc! Elle est trop génial celle là  quand je compare au reste n'empêche!


    AppKiDo est encore mieux...
  • schlumschlum Membre
    09:40 modifié #54
    dans 1235292737:

    J'ai trouvé ça:
    http://www.cocoabuilder.com/archive/message/cocoa/2005/6/22/139644

    Dans XCode 3, j'ai rajouté -Wstrict-selector-match dans Other Warning Flags et bingo !

    Line Location AppController.m:61: warning: multiple methods named '-initWithX:Y:' found
    Line Location CIVector.h:45: warning: using '-(id)initWithX:(CGFloat)x Y:(CGFloat)y'
    Line Location ClasseEssai.h:22: warning: also found '-(id)initWithX:(int)x Y:(int)y'




  • mpergandmpergand Membre
    09:40 modifié #55
    dans 1235299646:

    dans 1235292737:

    J'ai trouvé ça:
    http://www.cocoabuilder.com/archive/message/cocoa/2005/6/22/139644

    Dans XCode 3, j'ai rajouté -Wstrict-selector-match dans Other Warning Flags et bingo !

    Line Location AppController.m:61: warning: multiple methods named '-initWithX:Y:' found
    Line Location CIVector.h:45: warning: using '-(id)initWithX:(CGFloat)x Y:(CGFloat)y'
    Line Location ClasseEssai.h:22: warning: also found '-(id)initWithX:(int)x Y:(int)y'









    Mais avec Xcode 2.5, si la même option de compilation produit bien les mêmes warnings, le bug ne se produit pas.

    Il y a donc bien un problème avec le compilateur dans Xcode 3.

  • schlumschlum Membre
    09:40 modifié #56
    Oui, il me semblait bien que c'était un bug de l'Objective-C 2.0
    Probablement dû aux changements du runtime...
Connectez-vous ou Inscrivez-vous pour répondre.