Différence entre @class et #import
Greensource
Membre
Bonjour! Petite question, quelqu'un saurais me dire la différence qu'il y a entre la directive @class et #import?
J'avoue ne pas bien saisir les subtilités.
Merci,
Pierre
ps:Comment faire pour rechercher sur le forum "@class" et "#import"? A chaque fois il me renvois tous les sujets ou il voit "class" et "import" du coup il y a un nombre de résultat de malade!
J'avoue ne pas bien saisir les subtilités.
Merci,
Pierre
ps:Comment faire pour rechercher sur le forum "@class" et "#import"? A chaque fois il me renvois tous les sujets ou il voit "class" et "import" du coup il y a un nombre de résultat de malade!
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
#import charge tout le header
On utilise en général @class en cas de références croisées (pointeur/argument vers un objet A dans un objet B et pointeur/argument vers un objet B dans un objet A)
à‰quivalent à "class A;" en C++
Merci
Non, c'est pas plus léger parce qu'en général, quand on met @class dans le .h, il faut faire #import dans le .m
Exemple, dans une classe Plouf, si dans le .h tu as une variable d'instance de type [tt]Toto* monToto[/tt], comme dans le .h tu ne fais que déclarer la variable mais qu'il n'a pas besoin de savoir quelles sont les méthodes auxquelles la classe Toto sait répondre, un @class suffit.
Par contre dans le ".m" tu vas sûrement faire des [tt][monToto faitTruc][/tt] et là il faut qu'il sache que Toto répond (ou pas) à "faitTruc". Donc là il faut que tu importes "Toto.h" pour qu'il sache quelles méthodes sont déclarées dedans.
Après, en pratique on aura du coup quasiment toujours besoin de faire un #import "Toto.h" au moins dans "Plouf.m" pour pouvoir utiliser les méthodes de notre variable d'instance Toto dedans... Donc plutôt que de mettre @class dans le ".h" et #import dans le .m (ce qui serait somme toute une bonne pratique en fait mais bon), on met directement #import dans le .h et on s'embête pas :P
D'autant que parfois dans "Toto.h" il peut y avoir d'autres trucs utiles, je pense en particulier à des déclarations de @protocol utiles pour les delegate (si la classe Toto a une variable d'instance [tt]id<TotoDelegate> delegate[/tt] par exemple, moi je déclare le [tt]@protocol TotoDelegate[/tt] au début de Toto.h pour tout regrouper...)
Au final comme le dit schlum, le cas où l'on est obligé d'utiliser @class c'est dans le cas de références croisées, une classe A qui contient une variable d'instance de type B et cette classe B qui contient elle-même une variable d'instance de A... Si on met des #import partout, pour compiler A il va #importer A.h, qui devoir #importer B.h... qui lui va #importer A.h... et on s'en sortirait pas, d'où le @class qui ne fait que dire au compilo "je te dis juste que la classe B existe".
Mais si A.h importe B.h et B.h importe A.h, on aura au pre-processing d'un .m qui importe A.h :
Test.m :
->
->
Et il va se plaindre dans le contenu de B.h qu'il y a un truc (à propos de A) qu'il ne connaà®t pas.
Si on a un @class au lieu du #import :
-> OK
J'ai pas bien saisi le coup des delegate encore mais c'est par ce que je ne me suis pas encore penché dessus. Les protocols ça commence à venir aussi
Bon en tout cas merci à tous, zète bien sympa sur ce forum, et super réactif! Si j'arrive à faire quelques choses de mes dix doigts ça sera bien grâce à vous! :adios!:
A ce propos, j'ai remarqué qu'un @class ne suffit pas quand on veut utiliser les propriétés + @synthetize. Dans ce cas, il faut importer tout le header: je trouve que ça casse largement l'intérêt de @class sous objective-c 2.
Cela m'évite le casse-tête des références croisées éventuelles, et correspond aux besoins lors de la compilation, sous réserve naturellement que les fichiers .h ne soient pas multiples en terme de contenu.
Je crois que je vais aussi adopter cette méthode. Ca semble être adapter à beaucoup de situation.
Philippe en a pris l'habitude apparemment, et c'est une bonne chose, moi c'est pas encore une habitude mais comme je disais pour moi c'est pourtant la façon idéale de faire je pense. Comme ça t'es sûr de pas avoir de surprises...
Et en plus c'est mieux du côté des dépendances (et donc optimise la compilation avec le makefile qu'utilise Xcode sous le capot quand tu compiles), puisque si dans A.h tu importes "B.h" puis tu compiles... ben si à un moment tu modifies B.h et recompiles... ben il va recompiler A.h aussi et donc tous les fichiers qui l'importent... puisque le "B.h" sera inclus dans chacun ! Alors qu'avec un @class qui dit juste "je te dis que la classe B existe", bah même si tu rajoutes des méthodes à ton B.h (mais que tu n'utilises pas ces nouvelles méthodes dans tous tes fichiers qui importent B.h) ça va pas tout recompiler mais que le stricte nécessaire