@property et le reste

LeLaidLeLaid Membre
09:01 modifié dans API AppKit #1
Salut à  tous
J'ai encore un souci de débutant à  vous soumettre:  8--)

J'ai une classe qui a deux variables. J'ai ajouté l'instruction @property pour que les setter et getter soient automatiquement construits.

@interface PBMaClass : NSView <br />{	<br />	NSUInteger Largeur;<br />	NSUInteger Longueur;<br />}<br /><br />@property (readwrite) NSUInteger Largeur;<br />@property (readwrite) NSUInteger Longueur;<br /><br />@end


Dans l'implémentation j'initialise comme ceci:

@implementation PBMandelbrotView

@synthesize Largeur;
@synthesize Longueur;<br /><br />- (id) init<br />{<br />	if (self = [super init])<br />	{<br />		[Largeur setLargeur: 300];<br />		[Longueur setLongueur: 400]; <br />	}<br />	return(self);<br />}<br />@end


A la compilation j'ai un warning au niveau de
[Largeur setLargeur: 300];<br />[Longueur setLongueur: 400];


warning: invalid receiver type 'NSUInteger'  ???

Je comprends pas pourquoi???  >:(

Réponses

  • 09:01 modifié #2
    Je te conseil d'acheter un bon bouquin pour commencer. Ca ne sera pas de l'argent de perdue !
  • LeLaidLeLaid Membre
    09:01 modifié #3
    C'est ok. J'ai vu mon erreur...
    Je dois écrire [self setLongueur: 400]...

    PS. Des bouquins j'en ai achetés 3....
    Ca ne m'enpêche pas d'avoir des petites question que je me permet de poser dans la section débutant (qui, si je comprends bien le Français, est faite pour ça).

    Merci tout de même pour ton aide  ;D
  • MalaMala Membre, Modérateur
    février 2009 modifié #4
    Edit: je suis pas réveillé moi. J'avais pas fait attention que c'était des properties.

    Ceci dit, si c'est juste pour initialiser tes NSUInteger à  l'intérieur même de la classe, autant le faire directement...

    <br />- (id) init<br />{<br />&nbsp; &nbsp; if (self = [super init])<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; Largeur = 300;<br />&nbsp; &nbsp; &nbsp; &nbsp; Longueur = 400;<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return(self);<br />}<br />
    



  • schlumschlum Membre
    09:01 modifié #5
    à‰vite les majuscules au début des noms de ivars.
  • LeLaidLeLaid Membre
    09:01 modifié #6
    Oui mais là , si je comprends bien, je ne respecte plus trop les principes de la séparation interface/implémentation. Non?

    J'ai lu qu'il fallait éviter d'alloué une valeur de cette façon....
  • NoNo Membre
    09:01 modifié #7
    dans 1235393573:

    Oui mais là , si je comprends bien, je ne respecte plus trop les principes de la séparation interface/implémentation. Non?
    J'ai lu qu'il fallait éviter d'alloué une valeur de cette façon....


    Ici, l'@interface (partie qui déclare notamment tes variables d'instance) est intimement liée à  son @implementation.
    Donc, sans trop casser la paradigme objet, tu peux directement utiliser tes variables dans ta classe sans passer par les getter/setters...

    Ce qui est important, c'est effectivement de séparer interface d'une classe de l'implémentation d'une autre classe. Là , l'utilisation des setter/getters devient obligatoire.
  • LeLaidLeLaid Membre
    09:01 modifié #8
    Ah oui, je vois.
    Evidement s'il me venait à  l'idée de changer le nom d'une de mes iVars je devrais de toute façon modifier le reste (@property et le reste...).

    Ok, merci :)
    Pascal
  • Philippe49Philippe49 Membre
    09:01 modifié #9
    dans 1235390409:

    A la compilation j'ai un warning au niveau de
    [Largeur setLargeur: 300];<br />[Longueur setLongueur: 400];
    


    warning: invalid receiver type 'NSUInteger'  ???

    Je comprends pas pourquoi???  >:(



    La méthode setLargeur est une méthode de la classe, et non de la variable largeur.
    Il faut mettre soit  [self setLargeur:200];  soit self.largeur=200; soit largeur=200;


    dans 1235393573:

    J'ai lu qu'il fallait éviter d'alloué une valeur de cette façon....

    Pour un NSUinteger, il n'y a aucune allocation dynamique, aucun "alloc" si tu préfères.
    La mémoire nécessaire est prévue et réservée à  l'avance à  la création de l'instance.
  • GreensourceGreensource Membre
    09:01 modifié #10
    Si je peux me permettre une petit remarque, un ami vient de me signaler une différence à  ce niveau:

    self.largeur=200; soit largeur=200;

    Le premier appel le getter de largeur tandis que le second affecte directement largeur.
    Je le dit juste parce que ça ma étonné venant du monde Java.
  • Philippe49Philippe49 Membre
    février 2009 modifié #11
    self.largeur appelle le setter de largeur , et le second affecte directement largeur comme un code C.

    Si il n'y a pas de traitement spécial dans le setter, c'est-à -dire si on a simplement mis @synthesize NSUInteger largeur; il n'y a aucune différence car il s'agit ici d'un type simple (pas de retain/release par en dessous)
    Après cela, si on a mis un attribut readonly le setter n'existe pas, ou si on se fait son propre setter, c'est le code que l'on y a installé qui est exécuté.

    Autre remarque, avec Cocoa, des coordonnées, des longueurs, des largeurs sont en général des CGFloat. Mais bon, on peut avoir besoin exceptionnellement d'utiliser des entiers. 
  • MalaMala Membre, Modérateur
    09:01 modifié #12
    dans 1235404973:

    Si il n'y a pas de traitement spécial dans le setter, c'est-à -dire si on a simplement mis @synthesize NSUInteger largeur; il n'y a aucune différence...

    Fonctionnellement non par contre il est peut être important de signaler qu'au niveau performances c'est le jour et la nuit.
  • GreensourceGreensource Membre
    09:01 modifié #13
    dans 1235406476:

    dans 1235404973:

    Si il n'y a pas de traitement spécial dans le setter, c'est-à -dire si on a simplement mis @synthesize NSUInteger largeur; il n'y a aucune différence...

    Fonctionnellement non par contre il est peut être important de signaler qu'au niveau performances c'est le jour et la nuit.

    Tu pourrais précisez s'il te plais? Ca m'intéresse.  ;)

    dans 1235404973:

    Autre remarque, avec Cocoa, des coordonnées, des longueurs, des largeurs sont en général des CGFloat et des NSUInteger. Mais bon, on peut avoir besoin exceptionnellement d'utiliser des entiers. 

    Ah bon? Et pourquoi on utilise pas simplement des float et int de base?

  • Philippe49Philippe49 Membre
    février 2009 modifié #14
    dans 1235407749:

    dans 1235406476:

    dans 1235404973:

    Si il n'y a pas de traitement spécial dans le setter, c'est-à -dire si on a simplement mis @synthesize NSUInteger largeur; il n'y a aucune différence...

    Fonctionnellement non par contre il est peut être important de signaler qu'au niveau performances c'est le jour et la nuit.

    Tu pourrais précisez s'il te plais? Ca m'intéresse.  ;)



    Un million d'affectations avec un setter ==> 0.030 secondes
    Un million d'affectations avec une  fonction static inline ==> 0.023 secondes
    Un million d'affectations simples ==> 0.020 secondes
    #import &lt;Foundation/Foundation.h&gt;<br /><br /><br />@interface Toto : NSObject {<br />	NSInteger x;<br />}<br /><br />@property (readwrite)  NSInteger x;<br /><br />@end<br /><br />@implementation Toto<br />@synthesize x;<br />@end<br /><br />static inline void choose(NSInteger * ad) {<br />	*ad=random();<br />}	<br /><br /><br /><br />int main (int argc, const char * argv&#91;]) {<br />	Toto *t ;<br />	t=[[Toto alloc] init];<br />	NSInteger x;<br />	if(argv[1][0]==&#39;a&#39;) {<br />		for(int i=0;i&lt;1000000;i++)<br />			t.x=random();<br />	} else 	if(argv[1][0]==&#39;b&#39;) {<br />		for(int i=0;i&lt;1000000;i++)<br />			choose(&amp;x);<br />		t.x=x;<br />	} else {<br />		for(int i=0;i&lt;1000000;i++)<br />			x=random();<br />		t.x=x;		<br />	}<br />	NSLog(@&quot;%ld&#092;n&quot;,t.x);<br />	[t release];<br />	return 0;<br />}
    



    dans 1235407749:

    dans 1235404973:

    Autre remarque, avec Cocoa, des coordonnées, des longueurs, des largeurs sont en général des CGFloat et des NSUInteger. Mais bon, on peut avoir besoin exceptionnellement d'utiliser des entiers. 

    Ah bon? Et pourquoi on utilise pas simplement des float et int de base?

    Parce que les fonctions classiques de l'appKit sont en flottants (CGFloat maintenant, mais tu peux mettre float), pas en entier (NSInteger maintenant, mais tu peux mettre int).


  • MalaMala Membre, Modérateur
    09:01 modifié #15
    Grillé...
    Merci Philippe. ;)
Connectez-vous ou Inscrivez-vous pour répondre.